Codeforces Round #535 (Div. 3)
其实也是近一个月之前的一场cf了,div3真是吼啊。今天忽然想起来补完剩下的题。
前五道暴力模拟什么的略过不写了。
E2 Array and Segments (Hard version)
题意:给出大小为n的数组a,m个区间。你可以决定每个区间是否进行操作(对区间内的数全部减1),给出任一方案使得数组最大值与最小值的差最大。n<=1e5,m<=300
E2和E1的区别只有数据范围,E1可以暴力枚举选择每个数作为最小值的情况(将包含最小值的区间全部进行操作),每次更新答案,O(n2m)。
E2可以在此基础上进行改进。线段树进行区间操作查询最大值的优化比较好想。然后发现这个m很小…从m入手发现可以用所有区间的端点可以将数组分成不超过601段,在每一段内的i我们按照如上原则选择的操作是相同的,由此可以批量处理降低时间复杂度。
(然而代码写的就非常不优雅,我自己看完都想说这是什么辣鸡…甚至一年半没写线段树了吧。有机会可能会看看官方Tutorial里的方法重写。
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<vector> #define Max(a,b) (a>b?a:b) #define N 100005 #define INF 0x3f3f3f3f using namespace std; int read() {int x=0,f=1;char c=getchar();while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}return x*f; } int n,m,a[N],l[303],r[303]; int seg[606],ans=0; vector<int>A,cp; struct Node {int l,r,maxn,lazy; }t[N*4]; void build(int idx,int l,int r) {t[idx].l=l,t[idx].r=r;if(l==r){t[idx].maxn=a[l],t[idx].lazy=0;return;}int mid=(l+r)>>1;build(idx<<1,l,mid),build(idx<<1|1,mid+1,r);t[idx].maxn=Max(t[idx<<1].maxn,t[idx<<1|1].maxn); } void pushdown(int idx) {if(t[idx].lazy&&t[idx].l!=t[idx].r){int lz=t[idx].lazy;t[idx].lazy=0;t[idx<<1].lazy+=lz,t[idx<<1|1].lazy+=lz;t[idx<<1].maxn+=lz,t[idx<<1|1].maxn+=lz;} } void add(int idx,int l,int r,int w) {if(l<=t[idx].l&&r>=t[idx].r){t[idx].maxn+=w,t[idx].lazy+=w;return;}pushdown(idx);int mid=(t[idx].l+t[idx].r)>>1;if(r<=mid)add(idx<<1,l,r,w);else if(l>mid)add(idx<<1|1,l,r,w);else add(idx<<1,l,r,w),add(idx<<1|1,l,r,w);t[idx].maxn=Max(t[idx<<1].maxn,t[idx<<1|1].maxn); } int main() {n=read(),m=read();for(int i=1;i<=n;i++)a[i]=read();build(1,1,n);for(int i=1;i<=m;i++){l[i]=read(),r[i]=read();seg[i*2-1]=l[i],seg[i*2]=r[i];}sort(seg+1,seg+2*m+1),seg[0]=0;int cnt=unique(seg+1,seg+2*m+1)-seg-1;seg[cnt+1]=INF;int now=0,f;for(int i=1;i<=n;i++){if(i==seg[now]||(i>seg[now]&&i==seg[now+1])){f=0,cp.clear();if(i==seg[now+1])now++;for(int j=1;j<=m;j++){if(l[j]<=i&&r[j]>=i)f++,add(1,l[j],r[j],-1),cp.push_back(j);}}else if(i>seg[now]){now++,f=0,cp.clear();for(int j=1;j<=m;j++){if(l[j]<=seg[now-1]+1&&r[j]>=seg[now]-1)f++,add(1,l[j],r[j],-1),cp.push_back(j);}}int minnum=a[i]-f;if(t[1].maxn-minnum>ans){ans=t[1].maxn-minnum;A=cp;}if(i==seg[now]-1||i==seg[now]){for(int j=0;j<cp.size();j++)add(1,l[cp[j]],r[cp[j]],1);}}printf("%d\n%d\n",ans,A.size());for(int i=0;i<A.size();i++)printf("%d ",A[i]);return 0; }
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #include<cmath> #define Max(a,b) (a>b?a:b) #define N 200005 using namespace std; int read() {int x=0,f=1;char c=getchar();while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}return x*f; } int n,m,head[N],cnt=0,father1[N],dep[N],p[N][20],mlen[N][20]; bool used[N]; struct Node1 {int u,v,w; }Edges1[N]; bool operator < (Node1 A,Node1 B){return A.w<B.w;} struct Node2 {int nxt,to,w; }Edges2[N*2]; int findf(int x) {return (father1[x]==x)?x:(father1[x]=findf(father1[x]));} void addedge(int u,int v,int w) {Edges2[++cnt].nxt=head[u];head[u]=cnt;Edges2[cnt].to=v,Edges2[cnt].w=w; } void dfs(int u) {for(int i=head[u];~i;i=Edges2[i].nxt){int v=Edges2[i].to;if(v==p[u][0])continue;p[v][0]=u,dep[v]=dep[u]+1,mlen[v][0]=Edges2[i].w;dfs(v);} } void init() {for(int i=1;(1<<i)<=n;i++)for(int j=1;j<=n;j++)p[j][i]=p[p[j][i-1]][i-1],mlen[j][i]=max(mlen[j][i-1],mlen[p[j][i-1]][i-1]); } int lca(int x,int y) {int res=0;if(dep[x]>dep[y])swap(x,y);int f=dep[y]-dep[x];for(int i=0;(1<<i)<=f;i++)if(f&(1<<i))res=Max(res,mlen[y][i]),y=p[y][i];if(x!=y){for(int i=(int)log2(n);i>=0;i--)if(p[x][i]!=p[y][i])res=Max(res,mlen[x][i]),res=Max(res,mlen[y][i]),x=p[x][i],y=p[y][i];res=Max(res,mlen[x][0]),res=Max(res,mlen[y][0]),x=p[x][0];}return res; } int main() {memset(head,-1,sizeof(head));memset(dep,0,sizeof(dep));memset(used,0,sizeof(used));n=read(),m=read();for(int i=1;i<=m;i++)Edges1[i].u=read(),Edges1[i].v=read(),Edges1[i].w=read();sort(Edges1+1,Edges1+1+m);for(int i=1;i<=n;i++)father1[i]=i;int cnt=0;for(int i=1;i<=m;i++){int fu=findf(Edges1[i].u),fv=findf(Edges1[i].v);if(fu!=fv){cnt++;addedge(Edges1[i].u,Edges1[i].v,Edges1[i].w);addedge(Edges1[i].v,Edges1[i].u,Edges1[i].w);used[i]=1;father1[fu]=fv; }if(cnt==n-1)break;}dep[1]=mlen[1][0]=0;p[1][0]=1;dfs(1),init();int ans=0;for(int i=1;i<=m;i++){if(used[i])continue;int u=Edges1[i].u,v=Edges1[i].v;int maxlen=lca(u,v);if(maxlen==Edges1[i].w)ans++;}printf("%d\n",ans);return 0; }
这是那个Second Solution…只需要在Kruskal时把权值相同的边批量处理。
权值相同的边如果在最开始也加不进去就永远不可能在MST中出现,可以加进去的边有able条,并查集合并实际能用到的边uni条,则其余able-uni条边都需要权值++使MST唯一。
(如果一条有可能加入MST的边由于其他边被先考虑而没加进去,那这条边端点u,v间路径上的最大边权与它的权值相同,即可以拆掉另一条换这条。)
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #include<cmath> #define Max(a,b) (a>b?a:b) #define N 200005 using namespace std; int read() {int x=0,f=1;char c=getchar();while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}return x*f; } int n,m,head[N],cnt=0,father1[N],ans=0; struct Node1 {int u,v,w; }Edges1[N]; bool operator < (Node1 A,Node1 B){return A.w<B.w;} int findf(int x) {return (father1[x]==x)?x:(father1[x]=findf(father1[x]));} int main() {memset(head,-1,sizeof(head));n=read(),m=read();for(int i=1;i<=m;i++)Edges1[i].u=read(),Edges1[i].v=read(),Edges1[i].w=read();sort(Edges1+1,Edges1+1+m);for(int i=1;i<=n;i++)father1[i]=i;int cnt=0,able=0,uni=0,from=1;for(int i=1;i<=m;i++){int fu=findf(Edges1[i].u),fv=findf(Edges1[i].v);if(fu!=fv)able++;if(i==m||Edges1[i+1].w!=Edges1[i].w){for(int j=from;j<=i;j++){int fu=findf(Edges1[j].u),fv=findf(Edges1[j].v);if(fu!=fv)father1[fu]=fv,cnt++,uni++;}ans+=able-uni;able=uni=0,from=i;}}printf("%d\n",ans);return 0; }
转载于:https://www.cnblogs.com/Zars19/p/10392066.html
Codeforces Round #535 (Div. 3)相关推荐
- Codeforces Round #535 (Div. 3) [codeforces div3 难度测评]
hhhh感觉我真的太久没有接触过OI了 大约是前天听到JK他们约着一起刷codeforces,假期里觉得有些颓废的我忽然也心血来潮来看看题目 今天看codeforces才知道居然有div3了,感觉应该 ...
- Codeforces Round #535 (Div. 3)题解
A. TwodistinctpointsTwo\ distinct\ pointsTwo distinct points 题目大意就是给出两个区间的左右边界,输出两个数,满足两个数分别在两个区间内且这 ...
- Codeforces Round #535 (Div. 3) 解题报告
CF1108A. Two distinct points 做法:模拟 如果两者左端点重合就第二条的左端点++就好,然后输出左端点 #include <bits/stdc++.h> usin ...
- Codeforces Round #506 (Div. 3)
Codeforces Round #506 (Div. 3) 实习期间事不多,对div3 面向题解和数据编程了一波 A. Many Equal Substrings 题目链接 A题就是找后缀和前缀重合 ...
- Codeforces Round #563 (Div. 2)/CF1174
Codeforces Round #563 (Div. 2)/CF1174 CF1174A Ehab Fails to Be Thanos 其实就是要\(\sum\limits_{i=1}^n a_i ...
- 构造 Codeforces Round #302 (Div. 2) B Sea and Islands
题目传送门 1 /* 2 题意:在n^n的海洋里是否有k块陆地 3 构造算法:按奇偶性来判断,k小于等于所有点数的一半,交叉输出L/S 4 输出完k个L后,之后全部输出S:) 5 5 10 的例子可以 ...
- Codeforces Round #696 (Div. 2) (A ~ E)超高质量题解(每日训练 Day.16 )
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 Codeforces Round #696 (Div. 2) (A ~ E)超高质量题解 比赛链接:h ...
- Codeforces Round #712 Div.2(A ~ F) 超高质量题解(每日训练 Day.15 )
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 Codeforces Round #712 Div.2(A ~ F) 题解 比赛链接:https:// ...
- Codeforces Round #701 (Div. 2) A ~ F ,6题全,超高质量良心题解【每日亿题】2021/2/13
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 目录 A - Add and Divide B - Replace and Keep Sorted C ...
- Codeforces Round #700 (Div. 2) D2 Painting the Array II(最通俗易懂的贪心策略讲解)看不懂来打我 ~
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 整场比赛的A ~ E 6题全,全部题目超高质量题解链接: Codeforces Round #700 ...
最新文章
- 记录一次生产环境中Redis内存增长异常排查全流程!
- 使用 yum 安装Docker(CentOS 7下)
- ansible调用callbacks插件实现结果nosql输出回调
- Python中的Numpy模块(1,numpy创建)
- mysql榨包是什么意思_模块与包 Mysql与Oracle区别
- Clumsy 弱网络环境模拟工具使用介绍
- sdk怎么用_PLC不支持OPC UA怎么办?别问了看完你就懂了
- RabbitMQ安装|使用|概念|Golang开发
- webpack -- 无法将“webpack”项识别为 cmdlet 。。。
- [HTTP] HTTP消息
- 【电子签章】HTML格式合同转化成PDF文件 已下载
- Altium AD20分屏显示,交叉选择模式使用,原理图和PCB器件的同步选择
- ZUST蓝桥杯校内选拔赛(java,c)安吉校区
- Linux下可用的开源网络调试助手
- 马斯克:让我成功的其实是工程思维
- virtualization technology设置
- 前端开发必备(三)-----用js验证表单是否为空以及验证码是否输入正确
- 计算机开机没有显示是什么原因是什么情况,电脑开机后显示器没有反应解决方法...
- K-means 算法(基本用法)
- scanf()函数的用法
热门文章
- sqlserver2008r2通过发布和订阅的方式进行数据库同步
- poj_3468 伸展树
- 第九讲 自定义函数参数预定义
- TFS2010物理迁移workspace恢复
- 初入职场,你够聪明不?
- 织梦本地调试运行PHP不显示图片,织梦CMS手机端不显示图片的原因及解决方法!...
- (转)DPDK收发包处理流程01 -- 网卡初始化
- DPDK初始化分析(一)
- gdb调试出现“no debugging symbols found”
- Wifi Enable 启动过程