COJ 0650 绝世难题(一) 可爱的仙人掌
传送门:http://oj.cnuschool.org.cn/oj/home/problem.htm?problemID=620
绝世难题(一) 可爱的仙人掌 |
难度级别:E; 运行时间限制:1000ms; 运行空间限制:262144KB; 代码长度限制:2000000B |
试题描述
|
---“神犇是怎么样的。。。” ---“神犇就是这种**题拿过来半小时随便A。。。(๑•̀ㅂ•́)و✧”
绝世难题之可爱的仙人掌 -------------------------我是题目和吐槽的分割线-------------------------
chx童鞋最近迷上了图论中的环,结果有一天他做梦都梦见了环。。。(¯﹃¯) ---“你最近一直研究我啊那你知道我有什么小名嘛?(,,• ₃ •,,)” ---“噗。。。我怎么知道你告诉我呗。。。Σ( ° △ °|||)︴” ---“其实嘛,我的小名叫做仙人掌了啊~” 噗。。。chx脑中不禁脑补了一下。。。(ㆀ˘・з・˘) 噗噗噗。。。chx心想好吧你说是就算是吧(⊙ ▽ ⊙) ---“其实呢,在一个无向连通图中呢,如果每一条边都只属于一个简单环,我们就把这个图叫做仙人掌。。。如果图中每一个连通块都是一个萌萌哒仙人掌且没有自环,那么我们就把这个图称作是沙漠。。。” 呵呵。。。好吧真的 好好好形象啊!!!(๑•̀ㅂ•́)و✧ 如果一个无向图的每个连通块都是个仙人掌,且不存在自环,我们就称之为沙漠。 现在呢,为了证明你是玩转仙人掌的神犇,chx给你 n 个结点,从 1 到 n 标号。 初始时没有任何边,且每个结点 i 有个权值 wi (wi>0) 。每次进行如下操作之一:
link v uw:在结点 v,u 间连一条权值为 w 的边。 1≤v,u≤n 且 w 为正整数。 如果连边完成后图仍为沙漠,则输出 "ok"(不含引号)。 否则操作非法,撤销此次操作并输出 "failed"(不含引号)。
cut v uw:在结点 v,u 间删掉一条权值为 w 的边。 1≤v,u≤n 且 w 为正整数。 如果存在这样的边则输出 "ok"(不含引号)(如果有多条权值为 w 的边删去任意一条)。 否则操作非法,不进行操作并输出 "failed"(不含引号)。
query1 vu:查询结点 v 到结点 u 的最短路信息。 1≤v,u≤n。 输出两个用空格隔开的整数 min,σ,分别代表最短路上点权的最小值、和。 如果没有路可到达则 min=−1,σ=−1。 如果最短路不唯一则 min=−2,σ=−2。
query2 vu:查询以结点 v 为根,子仙人掌 u 的信息。 1≤v,u≤n。 以结点 v 为根,子仙人掌 u 的定义是,删掉v 到 u 之间的所有简单路径上的边之后,u 所在的连通块。 输出两个用空格隔开的整数 min,σ,分别代表子仙人掌 u 中点权的最小值、和。 如果 v,u 不连通则 min=−1,σ=−1。
add1 v ud:把结点 v 到结点 u 的最短路上的每一个结点的权值都加上 d。 1≤v,u≤n 且 d 为正整数。 如果有路可到达且最短路唯一,则输出 "ok"(不含引号) 否则操作非法,不进行操作并输出 "failed"(不含引号)。
add2 v ud:把以结点 v 为根,子仙人掌 u 的每一个结点的权值都加上 d。 1≤v,u≤n 且 d 为正整数。 如果 v,u 在同一个连通块里,则输出 "ok"(不含引号) 否则操作非法,不进行操作并输出 "failed"(不含引号)。
现在你来负责搞定这个问题吧。。。 |
输入
|
第一行两个用空格隔开的正整数 n,m 表示一共有 n 个结点,m 个操作。
接下来一行 n 个正整数,第 i 个正整数为 wi。 接下来 m 行,每行代表一个操作。 |
输出
|
对于每个操作,输出相应的结果。
|
输入示例
|
11 23
10 5 11 7 8 14 30 3 16 20 19 link 1 2 5 link 2 3 3 link 3 4 7 link 4 5 8 link 2 6 10 link 6 7 15 link 4 7 3 link 6 8 9 link 6 8 6 link 7 9 12 link 9 11 10 link 7 10 4 link 9 10 8 query1 6 11 query1 2 10 query2 8 7 add1 8 5 100 query1 1 7 query2 8 7 add2 11 7 1000 query1 8 3 add2 3 2 2333 query1 1 5 |
输出示例
|
ok
ok ok ok ok ok ok ok ok ok ok ok ok -2 -2 5 73 16 85 ok 5 263 16 185 ok 1005 4233 ok 1011 9907 |
其他说明
|
1≤n≤50000,1≤m≤250000。
保证 link 和 cut 操作中的 w 满足 1≤w≤10000,所以关于边权的计算不会超出 32 位有符号整数范围。 保证初始的 wi 不超过 109,保证所有 add1 和 add2 操作中的 d 之和不超过 109。 ---真心吐槽这道题应该是本OJ代码长度最长的题呦→_→chx童鞋的极限缩行可是写了612行呢。。。 |
题解:动态仙人掌哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈
最棒的仙人掌讲解看这里一共有四节:http://vfleaking.blog.163.com/blog/static/17480763420142176910962/
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 #include<queue> 6 #include<cstring> 7 #define PAU putchar(' ') 8 #define ENT putchar('\n') 9 #define MAXN 50005 10 #define MAXM 250005 11 #define is_NULL_tag(x) ((x)==0) 12 #define is_NULL_info(x) (x.size==0) 13 using namespace std; 14 inline int read(){ 15 int x=0,sig=1;char ch=getchar(); 16 while(!isdigit(ch)){if(ch=='-')sig=-1;ch=getchar();} 17 while(isdigit(ch))x=10*x+ch-'0',ch=getchar(); 18 return x*=sig; 19 } 20 inline void write(int x){ 21 if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x; 22 int len=0,buf[15];while(x)buf[len++]=x%10,x/=10; 23 for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return; 24 } 25 char ch; 26 inline void Pass_Pau(int x){while(x--) getchar();return;} 27 int n,Q; 28 struct Info{ 29 int mi,size; 30 long long sum; 31 }; 32 typedef int Tag; 33 const Tag NULL_TAG=0; 34 const Info NULL_INFO=(Info){2147483647,0,0}; 35 inline Info operator + (const Info &a,const Info &b){return (Info){std::min(a.mi,b.mi),a.size+b.size,a.sum+b.sum};} 36 inline Info operator * (const Info &a,const Tag &b){return a.size ? (Info){a.mi+b,a.size,a.sum+1LL*a.size*b}: a;} 37 struct splay_node{ 38 splay_node *s[2],*fa; 39 Info x,sum; 40 Tag tag,tag_sum; 41 inline void add_tag(Tag t){ 42 x=x*t;sum=sum*t; 43 tag=tag+t;tag_sum=tag_sum+t; 44 return; 45 } 46 inline void down(){ 47 if(is_NULL_tag(tag)) return; 48 if(s[0]) s[0]->add_tag(tag); 49 if(s[1]) s[1]->add_tag(tag); 50 tag=NULL_TAG; 51 return; 52 } 53 inline void update(){ 54 sum=x; 55 if(s[0]) sum=sum+s[0]->sum; 56 if(s[1]) sum=sum+s[1]->sum; 57 return; 58 } 59 }; 60 splay_node _splay[MAXN+MAXM]; 61 inline int get_parent(splay_node *x,splay_node *&fa){return (fa=x->fa) ? fa->s[1]==x : -1;} 62 inline void rotate(splay_node *x){ 63 splay_node *fa,*gfa; 64 int t1,t2; 65 t1=get_parent(x,fa); 66 t2=get_parent(fa,gfa); 67 if((fa->s[t1]=x->s[t1^1])) fa->s[t1]->fa=fa; 68 fa->fa=x;x->fa=gfa;x->s[t1^1]=fa; 69 if(t2!=-1) gfa->s[t2]=x; 70 fa->update(); 71 return; 72 } 73 inline void pushdown(splay_node *x){ 74 static splay_node *stack[MAXN+MAXM]; 75 int cnt=0; 76 while(x){ 77 stack[cnt++]=x; 78 x=x->fa; 79 } 80 while(cnt--) stack[cnt]->down(); 81 return; 82 } 83 inline splay_node * splay(splay_node *x){ 84 pushdown(x); 85 while(1){ 86 splay_node *fa,*gfa; 87 int t1,t2; 88 t1=get_parent(x,fa); 89 if(t1==-1) break; 90 t2=get_parent(fa,gfa); 91 if(t2==-1){ 92 rotate(x);break; 93 }else if(t1==t2){ 94 rotate(fa);rotate(x); 95 }else{ 96 rotate(x);rotate(x); 97 }; 98 } 99 x->update(); 100 return x; 101 } 102 inline splay_node * join(splay_node *a,splay_node *b){ 103 if(!a) return b; 104 if(!b) return a; 105 while(a->s[1]) a->down(),a=a->s[1]; 106 splay(a)->s[1]=b;b->fa=a; 107 a->update(); 108 return a; 109 } 110 struct lcc_node; 111 struct cycle{ 112 int A,B; 113 lcc_node *ex; 114 }; 115 struct lcc_node{ 116 lcc_node *s[2],*fa; 117 lcc_node *first,*last; 118 bool rev; 119 bool isedge; 120 bool mpath; 121 bool hasmpath; 122 bool mpathtag; 123 bool hasmpathtag; 124 bool hascyctag; 125 bool hascyc; 126 cycle *cyc; 127 cycle *cyctag; 128 int totlen; 129 int len; 130 int size; 131 Info x,sum,sub,ex,all; 132 Tag chain_tag,sub_tag,ex_tag_sum; 133 inline void add_rev_tag(){ 134 std::swap(s[0],s[1]); 135 std::swap(first,last); 136 rev^=1; 137 return; 138 } 139 inline void add_cyc_tag(cycle *c){ 140 if(isedge) cyc=c; 141 cyctag=c; 142 hascyctag=1; 143 hascyc=c; 144 return; 145 } 146 inline void add_mpath_tag(bool t){ 147 mpathtag=t; 148 hasmpathtag=1; 149 mpath=t&isedge; 150 hasmpath=t&(isedge|(size>1)); 151 return; 152 } 153 inline void add_chain_tag(Tag t) 154 { 155 if(is_NULL_tag(t)) return; 156 x=x*t;sum=sum*t; 157 chain_tag=chain_tag+t; 158 all=sum+sub; 159 return; 160 }; 161 inline void add_sub_tag(Tag t); 162 inline void down(){ 163 if(rev){ 164 if(s[0]) s[0]->add_rev_tag(); 165 if(s[1]) s[1]->add_rev_tag(); 166 rev=0; 167 } 168 if(hascyctag){ 169 if(s[0]) s[0]->add_cyc_tag(cyctag); 170 if(s[1]) s[1]->add_cyc_tag(cyctag); 171 hascyctag=0; 172 } 173 if(hasmpathtag){ 174 if(s[0]) s[0]->add_mpath_tag(mpathtag); 175 if(s[1]) s[1]->add_mpath_tag(mpathtag); 176 hasmpathtag=0; 177 } 178 if(!is_NULL_tag(chain_tag)){ 179 if(s[0]) s[0]->add_chain_tag(chain_tag); 180 if(s[1]) s[1]->add_chain_tag(chain_tag); 181 chain_tag=NULL_TAG; 182 } 183 if(!is_NULL_tag(sub_tag)){ 184 if(s[0]) s[0]->add_sub_tag(sub_tag); 185 if(s[1]) s[1]->add_sub_tag(sub_tag); 186 sub_tag=NULL_TAG; 187 } 188 return; 189 } 190 inline void update(); 191 }; 192 lcc_node lcc[MAXN+MAXM]; 193 lcc_node *_node_tot; 194 splay_node *splay_root[MAXN+MAXM]; 195 inline void lcc_node::add_sub_tag(Tag t){ 196 if(is_NULL_tag(t)) return; 197 sub=sub*t;ex=ex*t; 198 sub_tag=sub_tag+t; 199 ex_tag_sum=ex_tag_sum+t; 200 all=sum+sub; 201 // add tag to splay_root 202 int id=this-lcc; 203 if(splay_root[id]){ 204 splay_root[id]->add_tag(t); 205 } 206 } 207 inline void lcc_node::update(){ 208 totlen=len; 209 hascyc=cyc; 210 size=1; 211 hasmpath=mpath; 212 if(s[0]) totlen+=s[0]->totlen,hascyc|=s[0]->hascyc,size+=s[0]->size,hasmpath|=s[0]->hasmpath; 213 if(s[1]) totlen+=s[1]->totlen,hascyc|=s[1]->hascyc,size+=s[1]->size,hasmpath|=s[1]->hasmpath; 214 first=s[0]?s[0]->first:this; 215 last=s[1]?s[1]->last:this; 216 bool s0=s[0],s1=s[1]; 217 if(isedge){ 218 if(is_NULL_info(ex)){ 219 if(s0 && s1){ 220 sum=s[0]->sum+s[1]->sum; 221 sub=s[0]->sub+s[1]->sub; 222 }else if(s0){ 223 sum=s[0]->sum; 224 sub=s[0]->sub; 225 }else if(s[1]){ 226 sum=s[1]->sum; 227 sub=s[1]->sub; 228 }else{ 229 sub=sum=NULL_INFO; 230 } 231 }else{ 232 if(s0 && s1){ 233 sum=s[0]->sum+s[1]->sum; 234 sub=s[0]->sub+s[1]->sub+ex; 235 }else if(s0){ 236 sum=s[0]->sum; 237 sub=s[0]->sub+ex; 238 }else if(s[1]){ 239 sum=s[1]->sum; 240 sub=s[1]->sub+ex; 241 }else{ 242 sum=NULL_INFO; 243 sub=ex; 244 } 245 } 246 }else{ 247 splay_node *root=splay_root[this-lcc]; 248 if(root){ 249 if(s0 && s1){ 250 sum=s[0]->sum+s[1]->sum+x; 251 sub=s[0]->sub+s[1]->sub+root->sum; 252 }else if(s0){ 253 sum=s[0]->sum+x; 254 sub=s[0]->sub+root->sum; 255 }else if(s[1]){ 256 sum=s[1]->sum+x; 257 sub=s[1]->sub+root->sum; 258 }else{ 259 sub=root->sum; 260 sum=x; 261 } 262 }else{ 263 if(s0 && s1){ 264 sum=s[0]->sum+s[1]->sum+x; 265 sub=s[0]->sub+s[1]->sub; 266 }else if(s0){ 267 sum=s[0]->sum+x; 268 sub=s[0]->sub; 269 }else if(s[1]){ 270 sum=s[1]->sum+x; 271 sub=s[1]->sub; 272 }else{ 273 sum=x; 274 sub=NULL_INFO; 275 } 276 } 277 } 278 all=sum+sub; 279 return; 280 }; 281 inline lcc_node * new_edge_node(int u,int v,int len){ 282 lcc_node *ret=++_node_tot; 283 ret->s[0]=ret->s[1]=ret->fa=NULL; 284 ret->first=ret->last=ret; 285 ret->rev=0; 286 ret->isedge=1; 287 ret->hascyctag=ret->hascyc=0; 288 ret->cyc=ret->cyctag=NULL; 289 ret->totlen=ret->len=len; 290 ret->size=1; 291 ret->x=ret->sum=ret->sub=ret->ex=ret->all=NULL_INFO; 292 ret->chain_tag=ret->sub_tag=ret->ex_tag_sum=NULL_TAG; 293 return ret; 294 } 295 inline int get_parent(lcc_node *x,lcc_node *&fa){return (fa=x->fa) ? fa->s[0]==x?0:fa->s[1]==x?1:-1 : -1;} 296 inline void rotate(lcc_node *x){ 297 int t1,t2; 298 lcc_node *fa,*gfa; 299 t1=get_parent(x,fa); 300 t2=get_parent(fa,gfa); 301 if((fa->s[t1]=x->s[t1^1])) fa->s[t1]->fa=fa; 302 fa->fa=x;x->fa=gfa;x->s[t1^1]=fa; 303 if(t2!=-1) gfa->s[t2]=x; 304 fa->update(); 305 return; 306 } 307 inline void pushdown(lcc_node *x){ 308 static lcc_node *stack[MAXN+MAXM]; 309 int cnt=0; 310 while(1){ 311 stack[cnt++]=x; 312 lcc_node *fa=x->fa; 313 if(!fa || (fa->s[0]!=x && fa->s[1]!=x)) break; 314 x=fa; 315 } 316 while(cnt--) stack[cnt]->down(); 317 return; 318 } 319 inline lcc_node * splay(lcc_node *x){ 320 pushdown(x); 321 while(1){ 322 int t1,t2; 323 lcc_node *fa,*gfa; 324 t1=get_parent(x,fa); 325 if(t1==-1) break; 326 t2=get_parent(fa,gfa); 327 if(t2==-1){ 328 rotate(x);break; 329 }else if(t1==t2){ 330 rotate(fa);rotate(x); 331 }else{ 332 rotate(x);rotate(x); 333 } 334 } 335 x->update(); 336 return x; 337 } 338 inline int getrank(lcc_node *x){ 339 splay(x); 340 return 1+(x->s[0]?x->s[0]->size:0); 341 } 342 bool _attached[MAXN+MAXM]; 343 inline void detach_rch(lcc_node *x){ 344 if(!x->s[1]) return; 345 int X=x-lcc; 346 int id=x->s[1]->first-lcc; 347 _attached[id]=1; 348 splay_node *p=_splay+id; 349 p->s[0]=splay_root[X]; 350 if(splay_root[X]) splay_root[X]->fa=p; 351 p->s[1]=p->fa=NULL; 352 p->x=x->s[1]->all; 353 p->tag=p->tag_sum=NULL_TAG; 354 p->update(); 355 splay_root[X]=p; 356 x->s[1]=NULL; 357 return; 358 } 359 inline void attach_rch(lcc_node *x,lcc_node *y,int id){ 360 int X=x-lcc; 361 _attached[id]=0; 362 splay_node *p=_splay+id; 363 splay(p); 364 if(p->s[0]) p->s[0]->fa=NULL; 365 if(p->s[1]) p->s[1]->fa=NULL; 366 splay_root[X]=join(p->s[0],p->s[1]); 367 y->add_chain_tag(p->tag_sum); 368 y->add_sub_tag(p->tag_sum); 369 x->s[1]=y; 370 return; 371 } 372 inline void attach_rch(lcc_node *x,lcc_node *y,int id,int id2){ 373 if(_attached[id]) attach_rch(x,y,id); 374 else attach_rch(x,y,id2); 375 return; 376 } 377 inline void attach_rch(lcc_node *x,lcc_node *y){ 378 if(!y) return; 379 attach_rch(x,y,y->first-lcc); 380 return; 381 } 382 inline lcc_node * access(lcc_node *x){ 383 lcc_node *ret=NULL; 384 int last_ex_last_id; 385 while(x){ 386 lcc_node *t=splay(x)->s[0]; 387 if(!t){ 388 detach_rch(x); 389 if(ret) attach_rch(x,ret,ret->first-lcc,last_ex_last_id); 390 ret=x;x->update(); 391 x=x->fa; 392 continue; 393 } 394 while(t->s[1]) t->down(),t=t->s[1]; 395 if(!splay(t)->cyc){ 396 splay(x); 397 detach_rch(x); 398 if(ret) attach_rch(x,ret,ret->first-lcc,last_ex_last_id); 399 ret=x;x->update(); 400 x=x->fa; 401 continue; 402 } 403 cycle *c=t->cyc; 404 lcc_node *A=lcc+c->A,*B=lcc+c->B,*ex=splay(c->ex); 405 bool need_tag_down=false; 406 lcc_node *B_ex; 407 if(splay(B)->fa==A){ 408 detach_rch(B); 409 B->s[1]=ex;ex->fa=B;B->update(); 410 need_tag_down=true; 411 B_ex=B->s[0]->first; 412 }else if(splay(A)->fa==B){ 413 std::swap(c->A,c->B);std::swap(A,B);ex->add_rev_tag(); 414 detach_rch(B); 415 B->s[1]=ex;ex->fa=B;B->update(); 416 need_tag_down=true; 417 B_ex=B->s[0]->last; 418 }else{ 419 bool f=0; 420 if(getrank(A)>getrank(B)){ 421 std::swap(c->A,c->B);std::swap(A,B);ex->add_rev_tag(); 422 f=1; 423 } 424 splay(A)->s[1]->fa=NULL;A->s[1]=NULL;A->update(); 425 splay(B);detach_rch(B); 426 B->s[1]=ex;ex->fa=B;B->update(); 427 B_ex=f ? B->s[0]->last : B->s[0]->first; 428 } 429 // add tag to ex 430 Tag tag_ex=splay(B_ex)->ex_tag_sum; 431 B_ex->ex=NULL_INFO; 432 B_ex->update(); 433 ex=splay(B)->s[1]; 434 ex->add_chain_tag(tag_ex); 435 ex->add_sub_tag(tag_ex); 436 B->update(); 437 splay(x);c->B=x-lcc; 438 if(x->s[1]->totlen<x->s[0]->totlen) x->add_rev_tag(); 439 x->add_mpath_tag(x->s[1]->totlen==x->s[0]->totlen); 440 x->down(); 441 c->ex=x->s[1];x->s[1]->fa=NULL; 442 x->s[1]=NULL; 443 x->update(); 444 lcc_node *tmp=splay(x->first); 445 tmp->ex=c->ex->all; 446 tmp->ex_tag_sum=NULL_TAG; 447 tmp->update(); 448 splay(x); 449 if(ret) attach_rch(x,ret,ret->first-lcc,last_ex_last_id); 450 x->update(); 451 last_ex_last_id=c->ex->last-lcc; 452 if(splay(A)->s[1]) ret=x,x=x->fa; 453 else{ 454 if(need_tag_down) attach_rch(A,x,c->ex->last-lcc,x->first-lcc); 455 A->s[1]=x;x->fa=A;A->update(); 456 ret=A;x=A->fa; 457 } 458 } 459 return ret; 460 } 461 inline void setroot(int x){access(lcc+x)->add_rev_tag();}; 462 inline bool link(int u,int v,int len){ 463 if(u==v) return false; 464 setroot(u); 465 lcc_node *t=access(lcc+v); 466 while(t->s[0]) t->down(),t=t->s[0]; 467 if(splay(t)!=lcc+u){ 468 lcc_node *p=new_edge_node(u,v,len); 469 p->fa=splay(lcc+u); 470 lcc[u].s[0]=p; 471 lcc[u].fa=lcc+v; 472 lcc[u].update(); 473 splay(lcc+v)->s[1]=lcc+u; 474 lcc[v].update(); 475 return true; 476 } 477 if(t->hascyc) return false; 478 lcc_node *ex=new_edge_node(u,v,len); 479 cycle *c=new cycle((cycle){u,v,ex}); 480 ex->add_cyc_tag(c); 481 t->add_cyc_tag(c); 482 access(lcc+v); 483 return true; 484 } 485 inline bool cut(int u,int v,int len){ 486 if(u==v) return false; 487 setroot(u); 488 lcc_node *t=access(lcc+v); 489 while(t->s[0]) t->down(),t=t->s[0]; 490 if(splay(t)!=lcc+u) return false; 491 if(!t->hascyc){ 492 if(t->size!=3) return false; 493 if(t->totlen!=len) return false; 494 t=t->s[1]; 495 if(t->s[0]) t->down(),t=t->s[0]; 496 splay(t); 497 t->s[0]->fa=NULL;t->s[1]->fa=NULL; 498 return true; 499 } 500 t=splay(lcc+v)->s[0]; 501 while(t->s[1]) t->down(),t=t->s[1]; 502 cycle *c=splay(t)->cyc; 503 if(!c) return false; 504 t=splay(lcc+u)->s[1]; 505 while(t->s[0]) t->down(),t=t->s[0]; 506 if(splay(t)->cyc!=c) return false; 507 lcc_node *ex=c->ex; 508 if(ex->size==1 && ex->len==len){ 509 t->add_cyc_tag(NULL); 510 t->add_mpath_tag(0); 511 delete c; 512 return true; 513 } 514 if(t->size!=3 || t->len!=len) return false; 515 // lcc[u].mpath == 0 ! 516 ex->add_cyc_tag(NULL); 517 ex->add_mpath_tag(0); 518 ex->add_rev_tag(); 519 ex->add_sub_tag(t->ex_tag_sum); 520 ex->add_chain_tag(t->ex_tag_sum); 521 lcc[u].fa=lcc[v].fa=NULL; 522 while(ex->s[0]) ex->down(),ex=ex->s[0]; 523 splay(ex)->s[0]=lcc+u;lcc[u].fa=ex;ex->update(); 524 while(ex->s[1]) ex->down(),ex=ex->s[1]; 525 splay(ex)->s[1]=lcc+v;lcc[v].fa=ex;ex->update(); 526 delete c; 527 return true; 528 } 529 inline Info query_path(int u,int v){ 530 setroot(u); 531 lcc_node *t=access(lcc+v); 532 while(t->s[0]) t->down(),t=t->s[0]; 533 if(splay(t)!=lcc+u) return (Info){-1,-1,-1}; 534 if(t->hasmpath) return (Info){-2,-2,-2}; 535 return t->sum; 536 } 537 inline Info query_subcactus(int u,int v){ 538 setroot(u); 539 lcc_node *t=access(lcc+v); 540 while(t->s[0]) t->down(),t=t->s[0]; 541 if(splay(t)!=lcc+u) return (Info){-1,-1,-1}; 542 Info ret=splay(lcc+v)->x; 543 if(splay_root[v]) ret=ret+splay_root[v]->sum; 544 return ret; 545 } 546 inline bool modify_path(int u,int v,Tag tag){ 547 setroot(u); 548 lcc_node *t=access(lcc+v); 549 while(t->s[0]) t->down(),t=t->s[0]; 550 if(splay(t)!=lcc+u) return false; 551 if(t->hasmpath) return false; 552 t->add_chain_tag(tag); 553 return true; 554 } 555 inline bool modify_subcactus(int u,int v,Tag tag){ 556 setroot(u); 557 lcc_node *t=access(lcc+v); 558 while(t->s[0]) t->down(),t=t->s[0]; 559 if(splay(t)!=lcc+u) return false; 560 splay(lcc+v); 561 lcc[v].x=lcc[v].x*tag; 562 if(splay_root[v]) splay_root[v]->add_tag(tag); 563 lcc[v].update(); 564 return true; 565 } 566 void init(){ 567 n=read();Q=read(); 568 int i; 569 static int w[MAXN]; 570 for(i=1;i<=n;i++){ 571 w[i]=read(); 572 lcc[i].first=lcc[i].last=lcc+i; 573 lcc[i].size=1; 574 lcc[i].x=lcc[i].sum=lcc[i].all=(Info){w[i],1,w[i]}; 575 lcc[i].sub=lcc[i].ex=NULL_INFO; 576 lcc[i].chain_tag=lcc[i].sub_tag=lcc[i].ex_tag_sum=NULL_TAG; 577 } 578 _node_tot=lcc+n; 579 return; 580 } 581 void work(){ 582 for(int i=1;i<=Q;i++){ 583 char ch=getchar(); 584 while(ch<=32) ch=getchar(); 585 if(ch=='l'){ 586 Pass_Pau(3); 587 int u=read(),v=read(),len=read(); 588 puts(link(u,v,len) ? "ok" : "failed"); 589 }else if(ch=='c'){ 590 Pass_Pau(2); 591 int u=read(),v=read(),len=read(); 592 puts(cut(u,v,len) ? "ok" : "failed"); 593 }else if(ch=='q'){ 594 Pass_Pau(4); 595 ch=getchar(); 596 int u=read(),v=read(); 597 Info ret; 598 ret=ch=='1' ? query_path(u,v) : query_subcactus(u,v); 599 printf("%d %lld\n",ret.mi,ret.sum); 600 }else if(ch=='a'){ 601 Pass_Pau(2); 602 ch=getchar(); 603 int u=read(),v=read(),val=read(); 604 puts((ch=='1'?modify_path(u,v,val):modify_subcactus(u,v,val)) ? "ok" : "failed"); 605 }else puts("error"); 606 } 607 return; 608 } 609 void print(){ 610 return; 611 } 612 int main(){init();work();print();return 0;}