UOJ274 [清华集训2016] 温暖会指引我们前行 LCT最大生成树

Posted menhera

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UOJ274 [清华集训2016] 温暖会指引我们前行 LCT最大生成树相关的知识,希望对你有一定的参考价值。

题目分析:

差评,最大生成树裸题。hack数据还卡常。

 

代码:

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 
  4 const int maxn = 402000;
  5 
  6 struct LCT{
  7     int fa[maxn],lazy[maxn],ch[maxn][2],d1[maxn],d2[maxn];
  8     int val[maxn],tot[maxn],num;
  9     stack<int> sta;
 10     void push_up(int now){
 11     val[now] = min(d1[now],min(val[ch[now][0]],val[ch[now][1]]));
 12     tot[now] = d2[now] + tot[ch[now][0]] + tot[ch[now][1]];
 13     }
 14     void push_down(int now){
 15     if(lazy[now]){
 16         swap(ch[now][0],ch[now][1]);
 17         lazy[now]=0;
 18         lazy[ch[now][0]] ^= 1; lazy[ch[now][1]] ^= 1;
 19         lazy[0] = 0;
 20     }
 21     }
 22     int is_root(int now){return !(ch[fa[now]][0]==now||ch[fa[now]][1]==now);}
 23     void r0(int now,int dr){
 24     int ff = fa[now],gf = fa[ff],son = ch[now][dr];
 25     int flag = is_root(ff);
 26     ch[ff][dr^1] = son; fa[son] = ff;
 27     ch[now][dr] = ff; fa[ff] = now;
 28     fa[now] = gf;
 29     if(!flag){if(ch[gf][0] == ff) ch[gf][0] = now; else ch[gf][1] = now;}
 30     push_up(ff); push_up(now);
 31     fa[0] = 0;ch[0][0] = ch[0][1] = 0;
 32     }
 33     void splay(int now){
 34     int pp = now;
 35     while(!is_root(pp)) sta.push(pp),pp = fa[pp];
 36     sta.push(pp);
 37     while(!sta.empty()) push_down(sta.top()),sta.pop();
 38     while(!is_root(now)){
 39         if(is_root(fa[now])){
 40         if(ch[fa[now]][0] == now) r0(now,1); else r0(now,0);
 41         }else{
 42         int ff = fa[now],gf = fa[ff];
 43         int alpha = ch[gf][0]==ff,beta = ch[ff][0]==now;
 44         if(alpha^beta) r0(now,beta),r0(now,alpha);
 45         else r0(ff,alpha),r0(now,beta);
 46         }
 47     }
 48     }
 49     void access(int now){
 50     splay(now);ch[now][1] = 0;push_up(now);
 51     while(fa[now]){
 52         int nxt=fa[now];splay(nxt);ch[nxt][1]=now; push_up(nxt); now=nxt;
 53     }
 54     }
 55     void make_root(int now){
 56     access(now);
 57     splay(now);
 58     lazy[now] ^= 1;
 59     }
 60     void cut(int u,int v){
 61     make_root(u); access(v); splay(u);
 62     fa[v] = 0;
 63     if(ch[u][0] == v) ch[u][0] = 0; else ch[u][1] = 0;
 64     push_up(u);
 65     }
 66     void link(int u,int v){make_root(u); fa[u] = v;}
 67     int lft(int dt){
 68     splay(dt);
 69     if(lazy[dt]) push_down(dt);
 70     while(ch[dt][0]){
 71         dt = ch[dt][0];
 72         if(lazy[dt]) push_down(dt);
 73     }
 74     return dt;
 75     }
 76     int find_min(int now){
 77     splay(now);
 78     while(d1[now] != val[now]){
 79         if(val[ch[now][0]] == val[now]) now = ch[now][0];
 80         else now = ch[now][1];
 81     }
 82     return now;
 83     }
 84 }T;
 85 
 86 int n,m,pre[maxn];
 87 
 88 struct edge{int from,to,tmp,len;}edges[maxn];
 89 
 90 char str[7];
 91 
 92 int found(int x){
 93     int rx = x; while(pre[rx] != rx) rx = pre[rx];
 94     while(pre[x]!=rx){int tt = x; pre[x] = rx; x = tt;}
 95     return rx;
 96 }
 97 
 98 void work(){
 99     T.d1[0] = 2e9;T.val[0] = 2e9;T.d2[0] = 0;
100     for(int i=1;i<=n;i++){T.num++;T.d1[i] = 2e9; T.val[i] = 2e9; pre[i] = i;}
101     for(int i=1;i<=m;i++){
102     scanf("%s",str);
103     if(str[0] == f){
104         int id;scanf("%d",&id);
105         scanf("%d%d",&edges[id].from,&edges[id].to);
106         scanf("%d%d",&edges[id].tmp,&edges[id].len);
107         edges[id].from++;edges[id].to++;
108         T.d1[n+id+1] = edges[id].tmp; T.d2[n+id+1] = edges[id].len;
109         T.val[n+id+1] = edges[id].tmp; T.tot[n+id+1] = edges[id].len;
110         T.make_root(edges[id].from);
111         T.access(edges[id].to);
112          int pd = T.lft(edges[id].to);
113         if(pd == edges[id].from){
114         if(T.val[edges[id].to] > edges[id].tmp) continue;
115         int pla = T.find_min(edges[id].to);
116         T.make_root(pla);T.cut(pla,edges[pla-n-1].from);
117         T.cut(pla,edges[pla-n-1].to);
118         }
119         T.link(edges[id].from,n+id+1);T.link(edges[id].to,n+id+1);
120         pre[found(edges[id].from)] = found(edges[id].to);
121     }else{
122         if(str[0] == m){
123         int u,v; scanf("%d%d",&u,&v); v++;u++;
124         if(found(u) != found(v)){puts("-1");continue;}
125         T.make_root(u);    T.access(v); T.splay(v);
126         printf("%d
",T.tot[v]);
127         }else{
128         int id,l; scanf("%d%d",&id,&l);
129         T.make_root(n+id+1); T.d2[n+id+1] = l;
130         T.push_up(n+id+1);
131         }
132     }
133     }
134 }
135 
136 int main(){
137     scanf("%d%d",&n,&m);
138     work();
139     return 0;
140 }

 

以上是关于UOJ274 [清华集训2016] 温暖会指引我们前行 LCT最大生成树的主要内容,如果未能解决你的问题,请参考以下文章

UOJ274 [清华集训2016] 温暖会指引我们前行 LCT最大生成树

刷题UOJ #274 清华集训2016温暖会指引我们前行

UOJ 274 清华集训2016温暖会指引我们前行 ——Link-Cut Tree

[清华集训] 温暖会指引我们前行

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

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