题目描述

有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:

  1. 3
  2. 0 0 0
  3. 8
  4. A1 3 -20
  5. A1 2 20
  6. U 1 3
  7. A2 1 10
  8. F1 3
  9. F2 3
  10. A3 -10
  11. F3
输出样例#1:

  1. -10
  2. 10
  3. 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……

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

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

代码

  1. #include<bits/stdc++.h>
  2. #define MAXN 300005
  3. #define INF 0x7f7f7f7f
  4. using namespace std;
  5. int read(){
  6. int x=,t=;char c=getchar();
  7. while(c<''||c>''){if(c=='-')t=-;c=getchar();}
  8. while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
  9. return x*t;
  10. }
  11. int N,Q,a[MAXN],father[MAXN],cnt1,lazy[MAXN<<],X[MAXN],Y[MAXN],cnt2,cont,pos[MAXN],dfso[MAXN],vis[MAXN],L[MAXN],R[MAXN],last[MAXN];
  12. char s[];
  13. int find(int x){return father[x]==x?x:father[x]=find(father[x]);}
  14. struct Node{int l,r,Max;}tree[MAXN<<];
  15. struct Edge{int other,pre;}e[MAXN];
  16. struct Operation{int type,x,y;}q[MAXN];
  17. void connect(int x,int y){
  18. if(x==y)return;
  19. e[++cnt2]=(Edge){y,last[x]};
  20. last[x]=cnt2;
  21. }
  22. void DFS(int x){
  23. cont++;L[x]=R[x]=pos[x]=cont,dfso[cont]=x;              //dfso是dfs序数组,pos数组是点对应的dfs序位置
  24. for(int i=last[x];i;i=e[i].pre)DFS(e[i].other);
  25. }
  26. void Pushdown(int k){
  27. if(!lazy[k])return;
  28. tree[k<<].Max+=lazy[k],lazy[k<<]+=lazy[k];
  29. tree[k<<|].Max+=lazy[k],lazy[k<<|]+=lazy[k];
  30. lazy[k]=;
  31. }
  32. void Build_tree(int k,int l,int r){
  33. tree[k].Max=-INF;                            //初值赋成-INF
  34. tree[k].l=l,tree[k].r=r; int mid=l+r>>;
  35. if(l==r){tree[k].Max=a[dfso[l]];return;}
  36. Build_tree(k<<,l,mid); Build_tree(k<<|,mid+,r);
  37. tree[k].Max=max(tree[k<<].Max,tree[k<<|].Max);
  38. }
  39. void Modify(int k,int l,int r,int x){
  40. if(tree[k].l>r||tree[k].r<l)return;
  41. if(l<=tree[k].l&&tree[k].r<=r){tree[k].Max+=x,lazy[k]+=x;return ;}
  42. Pushdown(k);
  43. Modify(k<<,l,r,x); Modify(k<<|,l,r,x);
  44. tree[k].Max=max(tree[k<<].Max,tree[k<<|].Max);
  45. }
  46. int Query(int k,int l,int r){
  47. if(tree[k].l>r||tree[k].r<l)return -INF;                //越界返回-INF
  48. if(l<=tree[k].l&&tree[k].r<=r)return tree[k].Max;
  49. Pushdown(k);
  50. return max( Query(k<<,l,r),Query(k<<|,l,r) );
  51. }
  52. int main()
  53. {
  54. N=read();
  55. for(int i=;i<=N;i++)a[i]=read(),father[i]=i;
  56. Q=read();
  57. for(int i=;i<=Q;i++){
  58. scanf("%s",s);
  59. if(s[]=='U'){
  60. q[i].type=;
  61. int x,y;
  62. q[i].x=x=read(),q[i].y=y=read();
  63. int fx=find(x), fy=find(y);
  64. cnt1++; father[fy]=fx;
  65. X[cnt1]=fx, Y[cnt1]=fy;                //存一下要连的边,是连的祖先!
  66. }
  67. if(s[]=='A'){
  68. if(s[]=='')q[i].type=,q[i].x=read(),q[i].y=read(); //x点+v
  69. if(s[]=='')q[i].type=,q[i].x=read(),q[i].y=read(); //x点联通块+v
  70. if(s[]=='')q[i].type=,q[i].x=read(); //全体+v
  71. }
  72. if(s[]=='F'){
  73. if(s[]=='')q[i].type=,q[i].x=read(); //询问x点
  74. if(s[]=='')q[i].type=,q[i].x=read(); //询问x点所在块
  75. if(s[]=='')q[i].type=; //全体询问
  76. }
  77. }
  78. for(int i=cnt1;i>;i--)connect(X[i],Y[i]);
  79. for(int i=;i<=N;i++)if(!vis[find(i)]){
  80. DFS(find(i));vis[find(i)]=;                     //跑DFS序
  81. }
  82. for(int i=;i<=N;i++)father[i]=i;                    //复原并查集
  83. Build_tree(,,N);
  84. for(int i=;i<=Q;i++){
  85. if(q[i].type==){
  86. int fx=find(q[i].x),fy=find(q[i].y);
  87. L[fx]=min(L[fx],L[fy]), R[fx]=max(R[fx],R[fy]);    //合并时维护联通块对应区间的L,R
  88. father[fy]=fx;
  89. }
         //简单的线段树操作
  90. if(q[i].type==)Modify(,pos[q[i].x],pos[q[i].x],q[i].y);
  91. if(q[i].type==){int fx=find(q[i].x);Modify(,L[fx],R[fx],q[i].y);}
  92. if(q[i].type==)Modify(,,N,q[i].x);
  93. if(q[i].type==)printf("%d\n",Query(,pos[q[i].x],pos[q[i].x]));
  94. if(q[i].type==){int fx=find(q[i].x);printf("%d\n",Query(,L[fx],R[fx]));}
  95. if(q[i].type==)printf("%d\n",Query(,,N));
  96. }
  97. return ;
  98. }
    //haha

不正经吐槽

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

一遍写的比较顺利。

接着我就开始调错。

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

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

lazytag没有判断        怎么改都WrongAnswer

最后一次 发现错在了 ↓

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

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

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

推送

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

寻梦环游记 - Remember Me-泠鸢

歌手:泠鸢yousa

bzoj2333 [SCOI2011]棘手的操作(洛谷3273)的更多相关文章

  1. bzoj2333[SCOI2011]棘手的操作 洛谷P3273 [SCOI2011]棘手的操作

    2333? 先记一下吧,这题现在全部都是照着题解做的,因为怎么改都改不出来,只好对着题解改,以后还要再做过 以后再也不用指针了!太恶心了!空指针可不止直接特判那么简单啊,竟然还要因为空指针写奇怪的分类 ...

  2. 真--可并堆模板--BZOJ2333: [SCOI2011]棘手的操作

    n<=300000个点,开始是独立的,m<=300000个操作: 方法一:单点修改.查询,区间修改.查询?等等等等这里修改是块修改不是连续的啊,那就让他连续呗!具体方法:离线后,每次连接两 ...

  3. BZOJ2333 [SCOI2011]棘手的操作 堆 左偏树 可并堆

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ2333 题意概括 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i ...

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

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

  5. bzoj千题计划217:bzoj2333: [SCOI2011]棘手的操作

    http://www.lydsy.com/JudgeOnline/problem.php?id=2333 读入所有数据,先模拟一遍所有的合并操作 我们不关心联通块长什么样,只关心联通块内有谁 所以可以 ...

  6. 2019.01.17 bzoj2333: [SCOI2011]棘手的操作(启发式合并)

    传送门 启发式合并菜题. 题意:支持与连通块有关的几种操作. 要求支持连边,单点修改,连通块修改,全局修改和单点查值,连通块查最大值和全局最大值. 我们对每个连通块和答案用可删堆维护最大值,然后用启发 ...

  7. BZOJ2333:[SCOI2011]棘手的操作(Splay)

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

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

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

  9. bzoj2333 [SCOI2011]棘手的操作

    用set维护每个联通块里的最值,multiset维护所有块里的最值,并查集维护连通性,然后随便搞搞就行了,合并时候采用启发式合并.复杂度O(nlognlogn),大概勉强过的程度,反正跑的很慢就是了. ...

随机推荐

  1. RabbitMQ学习笔记(1)----RabbitMQ简介与安装

    ·1. 什么是RabbitMQ? RabbitMQ是流行的开源消息队列系统,用erlang语言开发.RabbitMQ是AMQP(高级消息队列协议)的标准实现. 而AMQP协议则是指:即Advanced ...

  2. testng+selnium+eclipse的测试框架运用

    一:TestNG在Eclipse中的安装(1)点击eclipse中的Help->Install New Software (2)点击[Add]按钮,输入相应的地址(3)勾选加载出来的TestNG ...

  3. 关于css3背景图片渐变的规则

    1. Webkit引擎的CSS3径向渐变语法        Webkit引擎下的老版本语法:-webkit-gradient([<type>],[<position> || & ...

  4. JS自定义功能函数实现动态添加网址参数修改网址参数值

    无论是前端开发还是后台设计,很多时候开发人员都需要获取当前或目标网址的相关信息.这个已有现成的内置对象属性可以直接调用了(下面是获取当前页面的参考代码) 复制代码 代码如下: <script t ...

  5. 【BZOJ3309】DZY Loves Math - 莫比乌斯反演

    题意: 对于正整数n,定义$f(n)$为$n$所含质因子的最大幂指数.例如$f(1960)=f(2^3 * 5^1 * 7^2)=3$,$f(10007)=1$,$f(1)=0$. 给定正整数$a,b ...

  6. vue 动态拼接地址,使用本地的图片不显示

    <el-col :span="4" v-for="(item, index) in listData" :key="index"> ...

  7. event 下鼠标坐标的获取

    event.clientX.event.clientY 鼠标相对于浏览器窗口可视区域的X,Y坐标(窗口坐标),可视区域不包括工具栏和滚动条.IE事件和标准事件都定义了这2个属性 event.pageX ...

  8. java源码之LinkedHashMap

    先盗两张图感受一下(来自:https://blog.csdn.net/justloveyou_/article/details/71713781) HashMap和双向链表的密切配合和分工合作造就了L ...

  9. Springboot 应用启动分析

    https://blog.csdn.net/hengyunabc/article/details/50120001#comments 一,spring boot quick start 在spring ...

  10. synchronized与static synchronized 的差别、synchronized在JVM底层的实现原理及Java多线程锁理解

    本Blog分为例如以下部分: 第一部分:synchronized与static synchronized 的差别 第二部分:JVM底层又是怎样实现synchronized的 第三部分:Java多线程锁 ...