Description

Input

第一行包含一个正整数testcase,表示当前测试数据的测试点编号。保证1≤testcase≤20。

第二行包含三个整数N,M,T,分别表示节点数、初始边数、操作数。第三行包含N个非负整数表示 N个节点上的权值。

接下来 M行,每行包含两个整数x和 y,表示初始的时候,点x和点y 之间有一条无向边, 接下来 T行,每行描述一个操作,格式为“Q x y k”或者“L x y ”,其含义见题目描述部分。

Output

对于每一个第一类操作,输出一个非负整数表示答案。

Sample Input

1

8 4 8

1 1 2 2 3 3 4 4

4 7

1 8

2 4

2 1

Q 8 7 3 Q 3 5 1

Q 10 0 0

L 5 4

L 3 2 L 0 7

Q 9 2 5 Q 6 1 6

Sample Output

2

2

1

4

2

HINT

对于第一个操作 Q 8 7 3,此时 lastans=0,所以真实操作为Q 8^0 7^0 3^0,也即Q 8 7 3。点8到点7的路径上一共有5个点,其权值为4 1 1 2 4。这些权值中,第三小的为 2,输出 2,lastans变为2。对于第二个操作 Q 3 5 1 ,此时lastans=2,所以真实操作为Q 3^2 5^2 1^2 ,也即Q 1 7 3。点1到点7的路径上一共有4个点,其权值为 1 1 2 4 。这些权值中,第三小的为2,输出2,lastans变为 2。之后的操作类似。

Source

Solution

码农题

看见只有合并和查询k大不难想到主席树+启发式合并,但是这题还要动态维护lca,所以还要写个lct。

合并的时候,因为要新加入一个点的权值(小的接到大的的根上,成为大的的直系儿子,所以要加上大的根的权值),所以小的部分整个要dfs一波来更新,启发式合并可以做到\(O(nlog^2n)\)。

对于动态维护lca,很显然能用lct维护,不过细节比较多,要注意pushdown的顺序以及时机,还有就是找lca就是access(x)之后在access(y)时,找到的最后一个拼接点。找lca的fa时,就在splay里面按照平衡树的排序方式找即可。

Code

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. #define N 80005
  4. //fastIO
  5. namespace IO
  6. {
  7. const int __S=(1<<21)+5;char __buf[__S],*__H,*__T;
  8. inline char getc()
  9. {
  10. if(__H==__T) __T=(__H=__buf)+fread(__buf,1,__S,stdin);
  11. if(__H==__T) return -1;return *__H++;
  12. }
  13. template <class __I>inline void read(__I &__x)
  14. {
  15. __x=0;char __c=getc();
  16. while(!isdigit(__c)) __c=getc();
  17. while(isdigit(__c)) __x=__x*10+__c-'0',__c=getc();
  18. }
  19. inline void readd(double &__x)
  20. {
  21. __x=0;double __fg=1.0;char __c=getc();
  22. while(!isdigit(__c)&&__c!='-') __c=getc();
  23. if(__c=='-') __fg=-1.0,__c=getc();
  24. while(isdigit(__c)) __x=__x*10.0+__c-'0',__c=getc();
  25. if(__c!='.'){__x=__x*__fg;return;}else while(!isdigit(__c)) __c=getc();
  26. double __t=1e-1;while(isdigit(__c)) __x=__x+1.0*(__c-'0')*__t,__t=__t*0.1,__c=getc();
  27. __x=__x*__fg;
  28. }
  29. inline void reads(char *__s,int __x)
  30. {
  31. char __c=getc();int __tot=__x-1;
  32. while(__c<'!'||__c>'~') __c=getc();
  33. while(__c>='!'&&__c<='~') __s[++__tot]=__c,__c=getc();
  34. __s[++__tot]='\0';
  35. }
  36. char __obuf[__S],*__oS=__obuf,*__oT=__oS+__S-1,__c,__qu[55];int __qr;
  37. inline void flush(){fwrite(__obuf,1,__oS-__obuf,stdout);__oS=__obuf;}
  38. inline void putc(char __x){*__oS++ =__x;if(__oS==__oT) flush();}
  39. template <class __I>inline void print(__I __x)
  40. {
  41. if(!__x) putc('0');
  42. if(__x<0) putc('-'),__x=-__x;
  43. while(__x) __qu[++__qr]=__x%10+'0',__x/=10;
  44. while(__qr) putc(__qu[__qr--]);
  45. }
  46. inline void prints(const char *__s,const int __x)
  47. {
  48. int __len=strlen(__s+__x);
  49. for(int __i=__x;__i<__len+__x;__i++) putc(__s[__i]);
  50. }
  51. inline void printd(double __x,int __d)
  52. {
  53. long long __t=(long long)floor(__x);print(__t);putc('.');__x-=(double)__t;
  54. while(__d--)
  55. {
  56. double __y=__x*10.0;__x*=10.0;
  57. int __c=(int)floor(__y);
  58. putc(__c+'0');__x-=floor(__y);
  59. }
  60. }
  61. inline void el(){putc('\n');}inline void sp(){putc(' ');}
  62. }using namespace IO;
  63. //value
  64. int T,n,m,q,tot,x,y,z,la,cnt,lim;
  65. int a[N*2],b[N*2],rt[N*2],sm[N*400],ls[N*400],rs[N*400],fa[N*2],f[N*2],c[N*2][2],re[N*2],to[N*2*2],he[N*2],ne[N*2*2],sz[N*2];
  66. char o[5];
  67. //basis
  68. void add(int x,int y){to[cnt]=y;ne[cnt]=he[x];he[x]=cnt++;}
  69. int find(int x){return x==f[x]?x:f[x]=find(f[x]);}
  70. //lct
  71. bool isrt(int x){return c[fa[x]][0]!=x&&c[fa[x]][1]!=x;}
  72. bool R(int x,int y){return c[x][1]==y;}
  73. void dn(int x){if(!re[x]) return;re[x]^=1;re[c[x][0]]^=1;re[c[x][1]]^=1;swap(c[x][0],c[x][1]);}
  74. void ro(int x)
  75. {
  76. int y=fa[x],z=fa[y],a=R(y,x),b=!a;if(!isrt(y)) c[z][R(z,y)]=x;
  77. fa[x]=z,fa[y]=x,fa[c[x][b]]=y;c[y][a]=c[x][b],c[x][b]=y;
  78. }
  79. void U(int x){if(fa[x]) U(fa[x]);dn(x);}
  80. void spl(int x){U(x);for(;!isrt(x);ro(x)) if(!isrt(fa[x])) ro(R(fa[x],x)==R(fa[fa[x]],fa[x])?fa[x]:x);}
  81. int acs(int x){int g;for(int y=0;x;y=x,x=fa[x]) spl(x),c[x][1]=y,g=x;return g;}
  82. void mrt(int x){acs(x);spl(x);re[x]^=1;}
  83. void lnk(int x,int y){mrt(x);fa[x]=y;}
  84. int lca(int x,int y){acs(x);return acs(y);}
  85. //segment
  86. void ins(int &y,int x,int l,int r,int v)
  87. {
  88. y=++tot;sm[y]=sm[x]+1;if(l==r) return;int mid=(l+r)>>1;
  89. if(v<=mid) rs[y]=rs[x],ins(ls[y],ls[x],l,mid,v);else ls[y]=ls[x],ins(rs[y],rs[x],mid+1,r,v);
  90. }
  91. int que(int a,int b,int c,int d,int l,int r,int k)
  92. {
  93. if(l==r) return l;int mid=(l+r)>>1,g=sm[ls[a]]+sm[ls[b]]-sm[ls[c]]-sm[ls[d]];
  94. return k<=g?que(ls[a],ls[b],ls[c],ls[d],l,mid,k):que(rs[a],rs[b],rs[c],rs[d],mid+1,r,k-g);
  95. }
  96. //merge
  97. void dfs(int x,int fa)
  98. {
  99. ins(rt[x],rt[fa],1,lim,a[x]);
  100. for(int i=he[x],y;~i;i=ne[i]) if((y=to[i])!=fa) dfs(y,x);
  101. }
  102. void merge(int x,int y)
  103. {
  104. if(sz[x]<sz[y]) swap(x,y);int a=find(x),b=find(y);
  105. sz[a]+=sz[b];f[b]=a;add(x,y);add(y,x);lnk(x,y);
  106. }
  107. //main
  108. int main()
  109. {
  110. memset(he,-1,sizeof(he));read(T);read(n);read(m);read(q);
  111. for(int i=1;i<=n;i++) read(a[i]),f[i]=i,sz[i]=1,b[i]=a[i];
  112. sort(b+1,b+n+1);lim=unique(b+1,b+n+1)-b-1;
  113. for(int i=1;i<=n;i++) a[i]=lower_bound(b+1,b+n+1,a[i])-b;
  114. for(int i=1;i<=n;i++) ins(rt[i],rt[0],1,lim,a[i]);
  115. for(int i=1;i<=m;i++) read(x),read(y),merge(x,y);
  116. for(int i=1;i<=q;i++)
  117. {
  118. reads(o,0);
  119. if(o[0]=='L') read(x),read(y),x^=la,y^=la,merge(x,y);
  120. else
  121. {
  122. read(x),read(y),read(z);x^=la,y^=la,z^=la;mrt(find(x));
  123. int Lc=lca(x,y),Fa;acs(Lc);spl(Lc);Fa=c[Lc][0];
  124. dn(Fa);while(c[Fa][1]) Fa=c[Fa][1],dn(Fa);
  125. print(la=b[que(rt[x],rt[y],rt[Lc],rt[Fa],1,lim,z)]),el();
  126. }
  127. }
  128. flush();
  129. }

[bzoj3123] [SDOI2013]森林 主席树+启发式合并+LCT的更多相关文章

  1. [BZOJ3123][Sdoi2013]森林 主席树+启发式合并

    3123: [Sdoi2013]森林 Time Limit: 20 Sec  Memory Limit: 512 MB Description Input 第一行包含一个正整数testcase,表示当 ...

  2. 【BZOJ-3123】森林 主席树 + 启发式合并

    3123: [Sdoi2013]森林 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 2738  Solved: 806[Submit][Status] ...

  3. Bzoj 3123: [Sdoi2013]森林(主席树+启发式合并)

    3123: [Sdoi2013]森林 Time Limit: 20 Sec Memory Limit: 512 MB Description Input 第一行包含一个正整数testcase,表示当前 ...

  4. BZOJ 3123: [Sdoi2013]森林 [主席树启发式合并]

    3123: [Sdoi2013]森林 题意:一个森林,加边,询问路径上k小值.保证任意时刻是森林 LCT没法搞,树上kth肯定要用树上主席树 加边?启发式合并就好了,小的树dfs重建一下 注意 测试点 ...

  5. luoguP3302 [SDOI2013]森林 主席树 启发式合并

    题目链接 luoguP3302 [SDOI2013]森林 题解 本来这题树上主席树暴力启发式合并就完了 结果把lca写错了... 以后再也不这么写了 复杂度\(O(nlog^2n)\) "f ...

  6. [SDOI2013]森林 主席树+启发式合并

    这题的想法真的很妙啊. 看到题的第一眼,我先想到树链剖分,并把\(DFS\)序当成一段区间上主席树.但是会发现在询问的时候,可能会非常复杂,因为你需要把路径拆成很多条轻链和重链,它们还不一定连续,很难 ...

  7. 【BZOJ 3123】 [Sdoi2013]森林 主席树启发式合并

    我们直接按父子关系建主席树,然后记录倍增方便以后求LCA,同时用并查集维护根节点,而且还要记录根节点对应的size,用来对其启发式合并,然后每当我们合并的时候我们都要暴力拆小的一部分重复以上部分,总时 ...

  8. BZOJ3123[Sdoi2013]森林——主席树+LCA+启发式合并

    题目描述 输入 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数.第三行包含N个非负 ...

  9. P3302 [SDOI2013]森林(主席树+启发式合并)

    P3302 [SDOI2013]森林 主席树+启发式合并 (我以前的主席树板子是错的.......坑了我老久TAT) 第k小问题显然是主席树. 我们对每个点维护一棵包含其子树所有节点的主席树 询问(x ...

随机推荐

  1. Java调用SQL Server的存储过程详解

    转载自Microsoft的官方文档 http://msdn2.microsoft.com/zh-cn/library/ms378995.aspx收录于 www.enjoyjava.net/f25 本文 ...

  2. 【334】Python Object-Oriented Programming

    Reference: Python中self用法详解 __init__ 方法: 私有变量. Reference: [290]Python 函数 class 里面的 function 创建与此一致,只是 ...

  3. GBDT,Adaboosting概念区分 GBDT与xgboost区别

    http://blog.csdn.net/w28971023/article/details/8240756 ============================================= ...

  4. 【Python爬虫】听说你又闹书荒了?豆瓣读书9.0分书籍陪你过五一

    说明 五一将至,又到了学习的季节.目前流行的各大书单主打的都是豆瓣8.0评分书籍,却很少有人来聊聊这9.0评分的书籍长什么样子.刚好最近学了学python爬虫,那就拿豆瓣读书来练练手. 爬虫 本来思路 ...

  5. Ubuntu开机自动挂载分区

    虽然我基本上都是使用Linux的,但是仍然有些时候需要切换到Windows(双系统),如果所有的分区都使用ext4等Linux分区格式,则在Windows下访问十分不方便. 因此,我一般会将一些两个系 ...

  6. Vue 路由缓存

    问题 在路由切换时不需要每次 点击都刷新子路由   尤其是在form表单的情况下  不能让用户 输入一半之后点击其他页面  再点回来 表单数据不见了 解决方案   vue 2.0     之中  有k ...

  7. [OS]windows 2012 server-Local users and groups-Backup Operators

    怎样找到windows 2012 server上的Backup Operators Press the Windows + R keys to open the Run dialog, type lu ...

  8. UX设计案例研究:建立更好的用户体验(重新设计Air Peace Airline网站)

    以下内容由Mockplus团队翻译整理,仅供学习交流,Mockplus是更快更简单的原型设计工具. 坐飞机旅行总是能给人带来很棒的体验,但我认为应该考虑预订航班时给用户带来的压力.在如今的数字世界,我 ...

  9. Android 实现在Activity中操作刷新另外一个Activity数据列表

    做android项目中遇到这样一个问题:有两个acticity,一个显示好友列表,另外一个显示会话列表,现在问题是在会话界面增加一个添加好友功能,添加好友后要求实时的刷新好友列表. 想了想,找了两种方 ...

  10. 关于int转char类型引发的一些思考

    signed char unsigned char