清华集训2016温暖会指引我们前行
Posted rddccd
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了清华集训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 ",Query(u , v)); 177 } 178 else{ 179 id = read() , l = read();id++; 180 upd(id , l); 181 } 182 } 183 return 0; 184 }
以上是关于清华集训2016温暖会指引我们前行的主要内容,如果未能解决你的问题,请参考以下文章
bzoj 4736 /uoj274清华集训2016温暖会指引我们前行 lct