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

语文题,LCT维护最大生成树即可

在寻找根的时候要Splay(root)…太可怕了以前都不知道

如果不Splay据说复杂度会不对

如果不这么干会TLE extra_test 5/7

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 struct node
  4 {
  5     int ch[2] , min_node;
  6     int fa , sum;
  7     bool rev;
  8 }splay[400005];
  9 struct edge
 10 {
 11     int u , v;
 12     int t , l , tc;
 13     bool q;
 14 }E[300005];
 15 int n , m , cnt;
 16 int c[400005];
 17 inline int read()
 18 {
 19     char ch = getchar();
 20     int s = 0;
 21     while(!('0' <= ch && ch <= '9')) ch = getchar();
 22     while('0' <= ch && ch <= '9'){
 23         s = s * 10 + ch - '0';
 24         ch = getchar();
 25     }
 26     return s;
 27 }
 28 inline bool is_root(int u)
 29 {
 30     return !(splay[splay[u].fa].ch[0] == u || splay[splay[u].fa].ch[1] == u);
 31 }
 32 inline bool which(int u)
 33 {
 34     return (u == splay[splay[u].fa].ch[1]);
 35 }
 36 void pd(int u)
 37 {
 38     if(splay[u].rev){
 39         swap(splay[u].ch[0] , splay[u].ch[1]);
 40         splay[splay[u].ch[0]].rev ^= 1;
 41         splay[splay[u].ch[1]].rev ^= 1;
 42         splay[u].rev = 0;
 43     }
 44     return;
 45 }
 46 int mnode;
 47 void rec(int u)
 48 {
 49     if(u > n) splay[u].sum = E[c[u]].l;
 50     else splay[u].sum = 0;
 51     splay[u].sum += splay[splay[u].ch[0]].sum + splay[splay[u].ch[1]].sum;
 52     if(u > n) mnode = u;
 53     else mnode = 0;
 54     if(splay[u].ch[0] && E[c[mnode]].t > E[c[splay[splay[u].ch[0]].min_node]].t) {mnode = splay[splay[u].ch[0]].min_node;}
 55     if(splay[u].ch[1] && E[c[mnode]].t > E[c[splay[splay[u].ch[1]].min_node]].t) {mnode = splay[splay[u].ch[1]].min_node;}
 56     splay[u].min_node =  mnode;
 57     return;
 58 }
 59 void rotate(int u)
 60 {
 61     int f = splay[u].fa;
 62     pd(f);pd(u);
 63     bool k = which(u);
 64     if(!is_root(f)) splay[splay[f].fa].ch[which(f)] = u;
 65     splay[u].fa = splay[f].fa;
 66     splay[splay[u].ch[!k]].fa = f;
 67     splay[f].ch[k] = splay[u].ch[!k];
 68     splay[u].ch[!k] = f;splay[f].fa = u;
 69     rec(f);rec(u);
 70     return;
 71 }
 72 void Splay(int u)
 73 {
 74     int f;
 75     while(!is_root(u)){
 76         f = splay[u].fa;
 77         if(is_root(f)) {rotate(u);}
 78         else if(which(u) == which(f)){rotate(f);rotate(u);}
 79         else {rotate(u);rotate(u);}
 80     }
 81     return;
 82 }
 83 void access(int u)
 84 {
 85     int y = 0;
 86     while(u){
 87         Splay(u);
 88         pd(u);splay[u].ch[1] = y;rec(u);
 89         y = u;u = splay[u].fa;
 90     }
 91     return;
 92 }
 93 inline void MRT(int u)
 94 {
 95     access(u);
 96     Splay(u);
 97     splay[u].rev ^= 1;
 98     return;
 99 }
100 inline void link(int u,int v)
101 {
102     MRT(u);splay[u].fa = v;
103 }
104 inline void cut(int u,int v)
105 {
106     MRT(u);access(v);Splay(v);
107     splay[v].ch[0] = 0;
108     splay[u].fa = 0;
109     rec(v);
110     return;
111 }
112 bool connect(int u,int v)
113 {
114     MRT(u);
115     access(v);Splay(v);pd(v);
116     while(splay[v].ch[0]) {v = splay[v].ch[0];pd(v);}
117     Splay(v); //据说不加会让复杂度不对的玩意
118     return u == v;
119 }
120 void Find(int u,int v,int t,int l,int id)
121 {
122     if(!connect(u , v)){
123         ++cnt;splay[cnt].min_node = cnt;splay[cnt].sum = l;
124         c[cnt] = id;
125         link(u , cnt);link(v , cnt);
126         E[id].q = 1;E[id].tc = cnt;
127         return;
128     }
129     MRT(u);access(v);Splay(v);
130     int p = splay[v].min_node;
131     if(E[c[p]].t < t){
132         cut(E[c[p]].u , p);
133         cut(E[c[p]].v , p);
134         ++cnt;splay[cnt].min_node = cnt;splay[cnt].sum = l;
135         c[cnt] = id;
136         link(u , cnt);link(v , cnt);
137         E[id].q = 1;E[c[p]].q = 0;E[id].tc = cnt;
138     }
139     else E[id].q = 0;
140     return;
141 }
142 int Query(int u,int v)
143 {
144     if(u == v) return 0;
145     if(!connect(u , v)) return -1;
146     MRT(u);
147     access(v);Splay(v);
148     return splay[v].sum;
149 }
150 void upd(int id,int l)
151 {
152     if(!E[id].q) return;
153     int u = E[id].tc;
154     while(!is_root(u)){
155         splay[u].sum += (l - E[id].l);
156         u = splay[u].fa;
157     }
158     E[id].l = l;
159     return;
160 }
161 int main()
162 {
163     n = read() , m = read();cnt = n;
164     int id , u ,v , t , l;
165     E[0].t = (1e9 + 7);
166     while(m--){
167         char ch = getchar();
168         if(ch == 'f'){
169             id = read() , u = read() , v = read() , t = read() , l = read();u++;v++;id++;
170             E[id].u = u , E[id].v = v;
171             E[id].t = t , E[id].l = l;
172             Find(u , v , t , l , id);
173         }
174         else if(ch == 'm'){
175             u = read() , v = read();v++,u++;
176             printf("%d\n",Query(u , v));
177         }
178         else{
179             id = read() , l = read();id++;
180             upd(id , l);
181         }
182     }
183     return 0;
184 }
View Code

 

转载于:https://www.cnblogs.com/RDDCCD/p/9155027.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值