当前位置: 首页 > news >正文

杂题笔记

CF2133F Flint and Steel

首先把每个能爆炸的苦力怕爆炸极限跑出来,配合苦力怕位置(核心)组一个结构体

注意到爆炸序列是合法当且仅当不存在两个被引爆的苦力怕,他们的互相包含对方的核心

那么相邻两个苦力怕存在三种合法情况,前者包含后者,后者包含前者,互不包含

\(f_i\) 为炸到 \(i\) 所需的最少苦力怕数,那么三种转移分两种优化转移:前者不包含后者,前者包含后者且后者不包含前者

各维护一棵线段树,第一种在跑到爆炸极限右端点时更新,然后在每个核心处转移。
第二种在核心处更新,在爆炸极限左端点处转移。
先转移后更新

同时为了保证合法性,进行右端点单修而非区修,防止严格更弱的区间夹在中间变出合法方案

#include<bits/stdc++.h>
#define N 500005
#define inf 100000000
using namespace std;
int x[N],L[N],R[N],num[N];
vector<int>pre[N],suf[N];
struct Ty{int u,val;}fa[N],dp[N];
Ty cmp(Ty a,Ty b){if(a.val<b.val)return a;return b;
}
bool over(int a,int b){return x[a]<x[b];}
struct Ig{Ty y[N<<2];void build(int u,int l,int r){y[u].val=inf;y[u].u=0;if(l==r)return;int mid=(l+r)/2;build(u*2,l,mid);build(u*2+1,mid+1,r);return;}void update(int u,int l,int r,int id,Ty val){if(l==r&&l==id){y[u]=cmp(val,y[u]);return;}int mid=(l+r)/2;if(id<=mid)update(u*2,l,mid,id,val);else update(u*2+1,mid+1,r,id,val);y[u]=cmp(y[u*2],y[u*2+1]);return;}Ty query(int u,int l,int r,int fl,int fr){if(l==fl&&r==fr)return y[u];int mid=(l+r)/2;if(fr<=mid)return query(u*2,l,mid,fl,fr);else if(fl>mid)return query(u*2+1,mid+1,r,fl,fr);else return cmp(query(u*2,l,mid,fl,mid),query(u*2+1,mid+1,r,mid+1,fr));}
}T1,T2;
signed main(){int T;scanf("%d",&T);while(T--){int n;Ty ans={0,inf};scanf("%d",&n);for(int i=1;i<=n;i++)fa[i]=dp[i]={0,inf};for(int i=1;i<=n;i++)scanf("%d",&x[i]);T1.build(1,1,n);T2.build(1,1,n);for(int i=1;i<=n;i++)if(x[i]>0){L[i]=max(1,i-x[i]+1);R[i]=min(n,i+x[i]-1);pre[L[i]].push_back(i);suf[R[i]].push_back(i);}for(int i=1;i<=n;i++){for(int j=0;j<pre[i].size();j++){if(i==1)fa[pre[i][j]]={0,0};else fa[pre[i][j]]=T2.query(1,1,n,max(1,i-1),R[pre[i][j]]-1);}if(x[i]>0){fa[i]=cmp(fa[i],T1.query(1,1,n,max(1,L[i]-1),R[i]));dp[i].u=i;dp[i].val=fa[i].val+1;T2.update(1,1,n,R[i],dp[i]);}for(int j=0;j<suf[i].size();j++){if(i==n)ans=cmp(ans,dp[suf[i][j]]);else T1.update(1,1,n,i,dp[suf[i][j]]);}}if(ans.val>1e7){printf("-1\n");for(int i=1;i<=n;i++){L[i]=R[i]=0;pre[i].clear();suf[i].clear();}continue;}printf("%d\n",ans.val);int top=0;int u=ans.u;while(u){num[++top]=u;u=fa[u].u;}sort(num+1,num+top+1,over);for(int i=1;i<=top;i++)printf("%d ",num[i]);printf("\n");for(int i=1;i<=n;i++){L[i]=R[i]=0;pre[i].clear();suf[i].clear();}}return 0;
}

CF2147F Exchange Queries

第一步转化:连出所有 \(p\to s,p\to p-1,s\to s-1\) 的边,那么问题就会转化成强联通缩点DAG图上可达点总数问题

第二步转化:注意到对于一条边 \((p_i,s_i)\),如果在强联通分量中存在 \(j\) 满足 \((p_i<p_j)+(s_i<s_j)=1\),那么边 \(i\)就可以合并进去,所以跑出来的 DAG 最多只有一个直接父节点和一个直接子节点,说白了就是条链

第三步转化:这玩意可以具象为两排点,对于每个 \(i\) 从上排点 \(p_i\) 向下排点 \(s_i\) 连边,那么每个强连通分量就是极大相交线段集合

第四步转化:推导一下可以发现每个极大相交线段集合包含的上下排点都正好填满一个连续段,那么只需要求出每个连续段的右端点即可

维护:显然的,对于边 \((p_i,s_i)\)\(p_i\sim s_i-1\) 都不能成为合法右端点,那么我们可以对这部分区间 +1,那么右端点集就是 0 构成的集合,在线段树上标记永久化再加上维护区间内答案,区间左右极值 0 就可以做了

#include<bits/stdc++.h>
#define int long long
#define N 100005
using namespace std;
struct Ty{int u,v,id;}x[N];
struct Ig{int tag,val,l,r;}y[N*4];
void build(int u,int l,int r){y[u].val=(r-l)*(l+r+1)/2;y[u].tag=0;y[u].l=l;y[u].r=r;if(l==r)return;int mid=(l+r)/2;build(u*2,l,mid);build(u*2+1,mid+1,r);return;
}
void update(int u,int l,int r,int fl,int fr,int val){if(l==fl&&r==fr){y[u].tag+=val;if(y[u].tag)y[u].val=y[u].l=y[u].r=0;else if(l==r){y[u].val=0;y[u].l=y[u].r=l;}else{y[u].val=y[u*2].val+y[u*2+1].val;y[u].l=y[u*2].l?y[u*2].l:y[u*2+1].l;y[u].r=y[u*2+1].r?y[u*2+1].r:y[u*2].r;if(y[u*2].r&&y[u*2+1].l)y[u].val+=(y[u*2+1].l-y[u*2].r)*y[u*2+1].l;}return;}int mid=(l+r)/2;if(fr<=mid)update(u*2,l,mid,fl,fr,val);else if(fl>mid)update(u*2+1,mid+1,r,fl,fr,val);else{update(u*2,l,mid,fl,mid,val);update(u*2+1,mid+1,r,mid+1,fr,val);}if(y[u].tag)y[u].val=y[u].l=y[u].r=0;else{y[u].val=y[u*2].val+y[u*2+1].val;y[u].l=y[u*2].l?y[u*2].l:y[u*2+1].l;y[u].r=y[u*2+1].r?y[u*2+1].r:y[u*2].r;if(y[u*2].r&&y[u*2+1].l)y[u].val+=(y[u*2+1].l-y[u*2].r)*y[u*2+1].l;}return;
}
signed main(){int T;scanf("%lld",&T);while(T--){int n,q;scanf("%lld%lld",&n,&q);for(int i=1;i<=n;i++)scanf("%lld",&x[i].u);for(int i=1;i<=n;i++)scanf("%lld",&x[i].v);build(1,1,n);for(int i=1;i<=n;i++)if(x[i].u<x[i].v)update(1,1,n,x[i].u,x[i].v-1,1);while(q--){int op;scanf("%lld",&op);if(op==1){int u,v;scanf("%lld%lld",&u,&v);if(x[u].u<x[u].v)update(1,1,n,x[u].u,x[u].v-1,-1);if(x[v].u<x[v].v)update(1,1,n,x[v].u,x[v].v-1,-1);swap(x[u].u,x[v].u);if(x[u].u<x[u].v)update(1,1,n,x[u].u,x[u].v-1,1);if(x[v].u<x[v].v)update(1,1,n,x[v].u,x[v].v-1,1);}else{int u,v;scanf("%lld%lld",&u,&v);if(x[u].u<x[u].v)update(1,1,n,x[u].u,x[u].v-1,-1);if(x[v].u<x[v].v)update(1,1,n,x[v].u,x[v].v-1,-1);swap(x[u].v,x[v].v);if(x[u].u<x[u].v)update(1,1,n,x[u].u,x[u].v-1,1);if(x[v].u<x[v].v)update(1,1,n,x[v].u,x[v].v-1,1);}printf("%lld\n",y[1].val+y[1].l*y[1].l);}}return 0;
}
http://www.rkmt.cn/news/13541.html

相关文章:

  • HyperWorks许可证服务器配置
  • 配电网一次设备
  • Visual Studio 项目中常用的Properties
  • 2025 最新权威推荐:防火皮革厂家 排行榜,B1 级阻燃 + E0 级环保实力品牌甄选B1级/建筑/审讯室/邮轮级防火皮革厂家推荐
  • 深入解析:华为全系列机型发展简史 机型与芯片的对照表
  • Volcano——配置理解
  • [转]bat/cmd将命令执行的结果赋值给变量
  • 题解:AT_abc424_f [ABC424F] Adding Chords
  • Software Crisis and Complexity
  • langgraphjs-gen-ui-examples
  • 2025 年节能咨询公司最新权威推荐排行榜:覆盖工业 / 建筑 / 数据中心等领域 TOP5 优质企业综合测评与选型指南发电厂/燃气/全域增效/服务器节能公司推荐
  • 2025 年无尘金刚砂源头厂家最新推荐排行榜:权威精选企业产能与品质深度解析无尘金刚砂材料/无尘金刚砂批发/无尘金刚砂喷砂厂家推荐
  • PySide6 之简易音乐播放器
  • 题解:P10005 [集训队互测 2023] 基础寄术练习题
  • 同步和互斥的基本概念
  • 盲盒一番赏小应用用户需求分析:从行为动机到功能诉求的深度拆解
  • C++ IO 库全方位解析:从基础到实战 - 指南
  • 洛谷P10112 [GESP202312 八级] 奖品分配
  • P10400 『STA - R5』消失的计算机
  • loki收集容器日志
  • 完整教程:dlib库关键点定位和疲劳检测
  • VKD233HH触控IC有两种输出方式“直接输出”和“锁存输出”单路触摸检测芯片
  • C# Avalonia 15- Animation- CachingTest
  • Ansible + Docker 部署 MinIO 集群
  • 自动遍历测试利器:开源工具AppCrawler 配置全解析
  • 250928
  • window 安全模式卸载任何软件
  • 定制笔记本电脑工厂排名:从基础代工到联合设计全面分析 - 教程
  • sv 去除字符串行尾空格函数
  • linux执行yum报错: except KeyboardInterrrupt, e