COJ 0650 绝世难题(一) 可爱的仙人掌

传送门:http://oj.cnuschool.org.cn/oj/home/problem.htm?problemID=620

绝世难题(一) 可爱的仙人掌
难度级别:E; 运行时间限制:1000ms; 运行空间限制:262144KB; 代码长度限制:2000000B
试题描述

---“神犇是怎么样的。。。”

---“神犇就是这种**题拿过来半小时随便A。。。(๑•̀ㅂ•́)و✧”

 

绝世难题之可爱的仙人掌

COJ 0650 绝世难题(一) 可爱的仙人掌

-------------------------我是题目和吐槽的分割线-------------------------

 

chx童鞋最近迷上了图论中的环,结果有一天他做梦都梦见了环。。。(¯﹃¯)

---“你最近一直研究我啊那你知道我有什么小名嘛?(,,• ₃ •,,)”

---“噗。。。我怎么知道你告诉我呗。。。Σ( ° △ °|||)︴”

---“其实嘛,我的小名叫做仙人掌了啊~”

噗。。。chx脑中不禁脑补了一下。。。(ㆀ˘・з・˘)

COJ 0650 绝世难题(一) 可爱的仙人掌

COJ 0650 绝世难题(一) 可爱的仙人掌

噗噗噗。。。chx心想好吧你说是就算是吧(⊙ ▽ ⊙)

---“其实呢,在一个无向连通图中呢,如果每一条边都只属于一个简单环,我们就把这个图叫做仙人掌。。。如果图中每一个连通块都是一个萌萌哒仙人掌且没有自环,那么我们就把这个图称作是沙漠。。。”

COJ 0650 绝世难题(一) 可爱的仙人掌

呵呵。。。好吧真的 好好好形象啊!!!(๑•̀ㅂ•́)و✧

如果一个无向图的每个连通块都是个仙人掌,且不存在自环,我们就称之为沙漠。

现在呢,为了证明你是玩转仙人掌的神犇,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;}

 

你可能感兴趣的:(OJ)