题目描述

有N个节点,标号从1到N,这N个节点一开始相互不连通。第i个节点的初始权值为a[i],接下来有如下一些操作:U x y: 加一条边,连接第x个节点和第y个节点A1 x v: 将第x个节点的权值增加vA2 x v: 将第x个节点所在的连通块的所有节点的权值都增加vA3 v: 将所有节点的权值都增加vF1 x: 输出第x个节点当前的权值F2 x: 输出第x个节点所在的连通块中,权值最大的节点的权值F3: 输出所有节点中,权值最大的节点的权值

输入输出格式

输入格式:

输入的第一行是一个整数N,代表节点个数。接下来一行输入N个整数,a[1], a[2], ..., a[N],代表N个节点的初始权值。再下一行输入一个整数Q,代表接下来的操作数。最后输入Q行,每行的格式如题目描述所示。

输出格式:

对于操作F1, F2, F3,输出对应的结果,每个结果占一行。

输入输出样例

输入样例#1:

3
0 0 0
8
A1 3 -20
A1 2 20
U 1 3
A2 1 10
F1 3
F2 3
A3 -10
F3

输出样例#1:

-10
10
10

说明

对于30%的数据,保证 N<=100,Q<=10000

对于80%的数据,保证 N<=100000,Q<=100000

对于100%的数据,保证 N<=300000,Q<=300000

对于所有的数据,保证输入合法,并且 -1000<=v, a[1], a[2], ..., a[N]<=1000

做法

我的想法是 离线+线段树区间修改, 预处理出每个操作联通块在DFS上的区间,然后上线段树就好了。

连边的时候,连的是这个点 并查集的祖先 ,而不是这个点,这样才能让所有相应联通块在连续的区间里(不理解就画一画)。

连边同时顺便维护每个联通块对应区间的L,R。

接着就线段树,

正经吐槽

细节很多。

由于是有负数的,一定在建立线段树时把值都赋成-INF,还有查询越界的return -INF

LazyTag……

预处理时并查集是找祖先连边用的,预处理完要把并查集清空(复原)。

别的细节我写在代码注释里面好了

代码

#include<bits/stdc++.h>
#define MAXN 300005
#define INF 0x7f7f7f7f
using namespace std;
int read(){int x=0,t=1;char c=getchar();while(c<'0'||c>'9'){if(c=='-')t=-1;c=getchar();}while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}return x*t;
}
int N,Q,a[MAXN],father[MAXN],cnt1,lazy[MAXN<<2],X[MAXN],Y[MAXN],cnt2,cont,pos[MAXN],dfso[MAXN],vis[MAXN],L[MAXN],R[MAXN],last[MAXN];
char s[5];
int find(int x){return father[x]==x?x:father[x]=find(father[x]);}
struct Node{int l,r,Max;}tree[MAXN<<2];
struct Edge{int other,pre;}e[MAXN];
struct Operation{int type,x,y;}q[MAXN];
void connect(int x,int y){if(x==y)return;e[++cnt2]=(Edge){y,last[x]};last[x]=cnt2;
}
void DFS(int x){cont++;L[x]=R[x]=pos[x]=cont,dfso[cont]=x;              //dfso是dfs序数组,pos数组是点对应的dfs序位置for(int i=last[x];i;i=e[i].pre)DFS(e[i].other);
}
void Pushdown(int k){if(!lazy[k])return;tree[k<<1].Max+=lazy[k],lazy[k<<1]+=lazy[k];tree[k<<1|1].Max+=lazy[k],lazy[k<<1|1]+=lazy[k];lazy[k]=0;
}
void Build_tree(int k,int l,int r){tree[k].Max=-INF;                            //初值赋成-INFtree[k].l=l,tree[k].r=r;    int mid=l+r>>1;if(l==r){tree[k].Max=a[dfso[l]];return;} Build_tree(k<<1,l,mid);        Build_tree(k<<1|1,mid+1,r);tree[k].Max=max(tree[k<<1].Max,tree[k<<1|1].Max);
}
void Modify(int k,int l,int r,int x){if(tree[k].l>r||tree[k].r<l)return;if(l<=tree[k].l&&tree[k].r<=r){tree[k].Max+=x,lazy[k]+=x;return ;}Pushdown(k); Modify(k<<1,l,r,x);        Modify(k<<1|1,l,r,x);tree[k].Max=max(tree[k<<1].Max,tree[k<<1|1].Max);
}
int Query(int k,int l,int r){if(tree[k].l>r||tree[k].r<l)return -INF;                //越界返回-INFif(l<=tree[k].l&&tree[k].r<=r)return tree[k].Max;Pushdown(k);return max( Query(k<<1,l,r),Query(k<<1|1,l,r) );
}
int main()
{N=read();for(int i=1;i<=N;i++)a[i]=read(),father[i]=i;Q=read();for(int i=1;i<=Q;i++){scanf("%s",s);if(s[0]=='U'){q[i].type=1;int x,y;q[i].x=x=read(),q[i].y=y=read();int fx=find(x),    fy=find(y);cnt1++;            father[fy]=fx;X[cnt1]=fx,        Y[cnt1]=fy;                //存一下要连的边,是连的祖先!}if(s[0]=='A'){if(s[1]=='1')q[i].type=2,q[i].x=read(),q[i].y=read();    //x点+v if(s[1]=='2')q[i].type=3,q[i].x=read(),q[i].y=read();    //x点联通块+v if(s[1]=='3')q[i].type=4,q[i].x=read();                    //全体+v
        }if(s[0]=='F'){if(s[1]=='1')q[i].type=5,q[i].x=read();                    //询问x点 if(s[1]=='2')q[i].type=6,q[i].x=read();                    //询问x点所在块 if(s[1]=='3')q[i].type=7;                                //全体询问
        }}for(int i=cnt1;i>0;i--)connect(X[i],Y[i]); for(int i=1;i<=N;i++)if(!vis[find(i)]){DFS(find(i));vis[find(i)]=1;                     //跑DFS序}for(int i=1;i<=N;i++)father[i]=i;                    //复原并查集Build_tree(1,1,N);for(int i=1;i<=Q;i++){    if(q[i].type==1){int fx=find(q[i].x),fy=find(q[i].y);L[fx]=min(L[fx],L[fy]),        R[fx]=max(R[fx],R[fy]);    //合并时维护联通块对应区间的L,Rfather[fy]=fx;}             //简单的线段树操作if(q[i].type==2)Modify(1,pos[q[i].x],pos[q[i].x],q[i].y);if(q[i].type==3){int fx=find(q[i].x);Modify(1,L[fx],R[fx],q[i].y);} if(q[i].type==4)Modify(1,1,N,q[i].x);if(q[i].type==5)printf("%d\n",Query(1,pos[q[i].x],pos[q[i].x]));if(q[i].type==6){int fx=find(q[i].x);printf("%d\n",Query(1,L[fx],R[fx]));}if(q[i].type==7)printf("%d\n",Query(1,1,N));}return 0;
}//haha

不正经吐槽

我是周六上午上课时写写画画 思考着这个题如何离线,下午和dalao们说了这个题 他们就去写在线的线段树合并了。

一遍写的比较顺利。

接着我就开始调错。

我没赋初值-INF         怎么改都是0

主函数里没有调用 Build_tree   怎么改都是-INF

lazytag没有判断        怎么改都WrongAnswer

最后一次 发现错在了 ↓

void Pushdown(int k){if(!lazy[k])return;tree[k<<1].Max+=k,lazy[k<<1]+=k;tree[k<<1|1].Max+=k,lazy[k<<1|1]+=k;lazy[k]=0;
}

把k当成了lazy[k] ,还看不出来 , 结果一Pushdown出现了一些本来就没有的数。弱智。

我开始质疑我的智商水平了

推送

http://music.163.com/#/song/524164335/?userid=476005944

寻梦环游记 - Remember Me-泠鸢

歌手:泠鸢yousa

转载于:https://www.cnblogs.com/Elfish/p/8053129.html

bzoj2333 [SCOI2011]棘手的操作(洛谷3273)相关推荐

  1. [bzoj2333] [SCOI2011]棘手的操作 (可并堆)

    //以后为了凑字数还是把题面搬上来吧2333 发布时间果然各种应景... Time Limit: 10 Sec  Memory Limit: 128 MB Description 有N个节点,标号从1 ...

  2. BZOJ2333 [SCOI2011]棘手的操作 【离线 + 线段树】

    题目 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i],接下来有如下一些操作: U x y: 加一条边,连接第x个节点和第y个节点 A1 x v: 将第x个节点的权 ...

  3. bzoj2333[SCOI2011]棘手的操作

    可以大力写一个平衡树启发式合并,除了每个连通块维护一个平衡树再对全局维护一个平衡树,每个节点表示某一个连通块的最大值.我的常数比较大,危险地卡过去了. #include<cstdio> # ...

  4. bzoj2333: [SCOI2011]棘手的操作 线段树+离线

    网上都是可并堆在线搞,其实直接离线处理处每个联通块,然后把他们放一起,然后点更新,区间询问就可以了. #include <iostream> #include <algorithm& ...

  5. 洛谷P3273 [SCOI2011] 棘手的操作 [左偏树]

    题目传送门 棘手的操作 题目描述 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i],接下来有如下一些操作: U x y: 加一条边,连接第x个节点和第y个节点 A1 ...

  6. 【BZOJ】2333: [SCOI2011]棘手的操作

    http://www.lydsy.com/JudgeOnline/problem.php?id=2333 题意: 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i], ...

  7. 【左偏树】【bzoj 2333】: [SCOI2011]棘手的操作

    http://www.lydsy.com/JudgeOnline/problem.php?id=2333 带lazy的左偏树,由于我不会写,所以借(chao)鉴(xi)了一下hzwer #includ ...

  8. BZOJ 2333 【SCOI2011】 棘手的操作

    题目链接:棘手的操作 网上的题解大部分都是在线用可并堆艹--但是树高严格\(\log\)的可并堆我不会啊--还是离线大法好-- 我们可以先把所有的合并操作用并查集给处理好,把得到的森林记录下来.然后, ...

  9. 洛谷P3688/uoj#291. [ZJOI2017]树状数组

    传送门(uoj) 传送门(洛谷) 这里是题解以及我的卡常数历程 话说后面那几组数据莫不是lxl出的这么毒 首先不难发现这个东西把查询前缀和变成了查询后缀和,结果就是查了\([l-1,r-1]\)的区间 ...

最新文章

  1. 【前沿技术】Facebook 硬件负责人,带摄像头的智能眼镜将在 10 年内成为常态
  2. .Net使用SignalR实现消息推送功能预研及Demo
  3. 【iCore2双核心板】SRAM 读写实验(基于Verilog语言)
  4. python花钱培训值吗-Python培训费用高不高?Python培训真的值得吗?
  5. Nacos源码DistroConsistencyServiceImpl
  6. java NIO和Reactor模式
  7. 作为深度学习最强框架的TensorFlow如何进行时序预测!(转)
  8. win10系统,字体及软件内容特别小(亲试有效)
  9. 项目绩效考核管理有何方法?这7大考核方案你都知道吗?
  10. 简单通用文章系统后台管理模板
  11. html5 渐变动画效果图,html5+css3城市场景动画_觉唯设计
  12. python 函数与部分使用示例
  13. FTP连接时出现“227 Entering Passive Mode” 的解决方法
  14. 萬丈雄心Soaring Ambitions
  15. linux intel wifi驱动,ubuntu 8.04下面 Intel WIFI link 5100无线网卡驱动安装
  16. Tableau阈值设置及其使用
  17. python 均线斜率怎么计算_高频交易算法研发心得--均线算法
  18. mac下网络监测工具
  19. ClinChoice昆翎完成对莱必宜的并购;西湖欧米完成Pre-A轮数亿元融资 | 医药健闻...
  20. 浙江省交通数字化改革行动方案来了!

热门文章

  1. python的jupyter的使用教程-如何优雅地使用 Jupyter?
  2. python使用教程pandas-「Python」pandas入门教程
  3. python request-python-request-各方法使用及格式
  4. python绘制动态模拟图-Python 模拟生成动态产生验证码图片的方法
  5. python中读取文件内容-Python从文件中读取数据(2)
  6. python利器的使用-Python数据科学利器
  7. python初学工资-python工资高还是java?
  8. python操作excel-python操作excel
  9. 零基础学python需要多久-零基础学Python要多久
  10. php和python学哪个-PHP Vs Python 学习哪个比较好?