[关闭]
@ysner 2018-09-18T11:01:50.000000Z 字数 2319 阅读 1744

【清华集训2016】温暖会指引我们前行

LCT


题面

戳我

解析

既然题目中把字典序的定义倒过来了,就说明要我们动态维护最大生成树(温度)。
显然只有能胜任这种操作。

鉴于只能维护点权,所以我们对每条边新建一个点,点权为边长,然后新点与两端点相连。
然后同时维护路径长度的和即可。

注意修改点信息时要那个点。

  1. #include<iostream>
  2. #include<cstring>
  3. #include<cmath>
  4. #include<cstdio>
  5. #include<cstdlib>
  6. #include<algorithm>
  7. #define ll long long
  8. #define re register
  9. #define il inline
  10. #define ls t[0][x]
  11. #define rs t[1][x]
  12. #define fp(i,a,b) for(re int i=a;i<=b;i++)
  13. #define fq(i,a,b) for(re int i=a;i>=b;i--)
  14. using namespace std;
  15. const int N=5e5+100;
  16. int n,m,f[N],tag[N],t[2][N],sta[N],top,val[N],tem[N],p[N];
  17. ll s[N];
  18. struct dat{int u,v;}a[N];
  19. il ll gi()
  20. {
  21. re ll x=0,t=1;
  22. re char ch=getchar();
  23. while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
  24. if(ch=='-') t=-1,ch=getchar();
  25. while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
  26. return x*t;
  27. }
  28. il void upd(re int x)
  29. {
  30. s[x]=s[ls]+s[rs]+val[x];p[x]=x;
  31. if(ls&&tem[p[ls]]<tem[p[x]]) p[x]=p[ls];
  32. if(rs&&tem[p[rs]]<tem[p[x]]) p[x]=p[rs];
  33. }
  34. il int son(re int x){return x==t[1][f[x]];}
  35. il int isrt(re int x){return x!=t[0][f[x]]&&x!=t[1][f[x]];}
  36. il void rev(re int x){if(!x) return;swap(ls,rs);tag[x]^=1;}
  37. il void pushdown(re int x)
  38. {
  39. if(!tag[x]) return;
  40. rev(ls);rev(rs);tag[x]=0;
  41. }
  42. il void rotate(re int x)
  43. {
  44. re int y=f[x],z=f[y],c=son(x);
  45. t[c][y]=t[c^1][x];if(t[c][y]) f[t[c][y]]=y;
  46. f[x]=z;if(!isrt(y)) t[son(y)][z]=x;
  47. t[c^1][x]=y;f[y]=x;upd(y);
  48. }
  49. il void splay(re int x)
  50. {
  51. sta[top=1]=x;
  52. for(re int i=x;!isrt(i);i=f[i]) sta[++top]=f[i];
  53. while(top) pushdown(sta[top--]);
  54. for(re int y=f[x];!isrt(x);rotate(x),y=f[x])
  55. if(!isrt(y)) son(x)^son(y)?rotate(x):rotate(y);
  56. upd(x);
  57. }
  58. il void access(re int x){for(re int y=0;x;y=x,x=f[x]) splay(x),rs=y,upd(x);}
  59. il void makert(re int x){access(x);splay(x);rev(x);}
  60. il int findrt(re int x){access(x);splay(x);while(ls) x=ls;splay(x);return x;}
  61. il void split(re int x,re int y){makert(x);access(y);splay(y);}
  62. il void link(re int x,re int y){makert(x);f[x]=y;}
  63. il void cut(re int x,re int y){split(x,y);t[0][y]=f[x]=0;upd(y);}
  64. il int Query(re int x,re int y){split(x,y);return s[y];}
  65. int main()
  66. {
  67. n=gi();m=gi();
  68. fp(i,1,n) tem[i]=2e9;
  69. fp(i,1,m)
  70. {
  71. re char op[10];scanf("%s",op);
  72. if(op[0]=='f')
  73. {
  74. re int id=gi()+n+1,u=gi()+1,v=gi()+1;
  75. tem[id]=gi(),val[id]=gi();
  76. a[id]=(dat){u,v};
  77. if(findrt(u)^findrt(v)) link(u,id),link(v,id);
  78. else
  79. {
  80. split(u,v);re int pos=p[v];
  81. if(tem[pos]<tem[id])
  82. {
  83. cut(a[pos].u,pos);cut(a[pos].v,pos);
  84. link(u,id);link(v,id);
  85. }
  86. }
  87. }
  88. if(op[0]=='m')
  89. {
  90. re int u=gi()+1,v=gi()+1;
  91. if(findrt(u)^findrt(v)) {puts("-1");continue;}
  92. printf("%d\n",Query(u,v));
  93. }
  94. if(op[0]=='c')
  95. {
  96. re int id=gi()+n+1,w=gi();
  97. val[id]=w;splay(id);
  98. }
  99. }
  100. return 0;
  101. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注