日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

COJ 1006 树上操作

發(fā)布時間:2024/9/5 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 COJ 1006 树上操作 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

傳送門:http://oj.cnuschool.org.cn/oj/home/problem.htm?problemID=979

?

WZJ的數(shù)據(jù)結(jié)構(gòu)(六)
難度級別:D; 運(yùn)行時間限制:1000ms; 運(yùn)行空間限制:51200KB; 代碼長度限制:2000000B
試題描述

給你一棵N個節(jié)點(diǎn)的無根樹,邊之間有權(quán)值。請你設(shè)計(jì)一個數(shù)據(jù)結(jié)構(gòu),進(jìn)行以下兩種操作:

1.修改:給你a、b,將第a條邊的權(quán)值改為b。

2.詢問:給你a、b,輸出從a到b路徑上的最大值、最小值與權(quán)值和,如果a=b,輸出"error"。

輸入
第一行為一個正整數(shù)N。
接下來N-1行為每一條邊,每行3個正整數(shù)a,b,c,表示有一條從a到b權(quán)值為c的邊(從1開始編號)。
第N+1行為一個正整數(shù)Q,表示Q次操作。
接下來Q行為每一次詢問,每行3個正整數(shù)t,a,b,若t=1表示詢問,t=0表示修改。
輸出
對于每一次詢問,輸出三個正整數(shù),即最大值、最小值與權(quán)值和,如果a=b,輸出"error"。
輸入示例
5?
1?2?4
1?4?5
3?4?6
2?5?7
4
1?1?5
1?2?5
0?1?2
1?1?5
輸出示例
7?4?11
7?7?7
7?2?9
其他說明
1<=N,Q<=50000
1<=c<=1000
詢問中的1<=a,b<=N
修改中的1<=a<=N-1,1<=b<=1000

題解:懶得寫樹鏈剖分了LCT走起

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 using namespace std; 10 const int maxn=100000+10,inf=-1u>>1; 11 inline int read(){ 12 int x=0,sig=1;char ch=getchar(); 13 while(!isdigit(ch)){if(ch=='-')sig=-1;ch=getchar();} 14 while(isdigit(ch))x=10*x+ch-'0',ch=getchar(); 15 return x*=sig; 16 } 17 inline void write(int x){ 18 if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x; 19 int len=0,buf[15];while(x)buf[len++]=x%10,x/=10; 20 for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return; 21 } 22 struct node { 23 int x,mi,mx,sm,set;bool rev; 24 node *ch[2],*fa; 25 inline void add_rev_tag(){ 26 swap(ch[0],ch[1]);rev^=1;return; 27 } 28 inline void add_set_tag(int a){ 29 x=set=a; 30 if(mi!=inf) mi=set; 31 if(mx!=-inf) mx=set; 32 } 33 inline void down(){ 34 if(rev){ 35 if(ch[0]) ch[0]->add_rev_tag(); 36 if(ch[1]) ch[1]->add_rev_tag(); 37 rev=0; 38 } 39 if(set){ 40 if(ch[0]) ch[0]->add_set_tag(set); 41 if(ch[1]) ch[1]->add_set_tag(set); 42 set=0; 43 } 44 return; 45 } 46 inline void update(){ 47 sm=x;mi=inf;mx=-inf; 48 if(ch[0]) sm+=ch[0]->sm,mi=min(mi,ch[0]->mi),mx=max(mx,ch[0]->mx); 49 if(ch[1]) sm+=ch[1]->sm,mi=min(mi,ch[1]->mi),mx=max(mx,ch[1]->mx); 50 if(!x) return; 51 mi=min(x,mi); 52 mx=max(x,mx); 53 return; 54 } 55 }lct[maxn]; 56 inline int get_parent(node *x,node *&fa){return (fa=x->fa)?fa->ch[0]==x?0:fa->ch[1]==x?1:-1:-1;} 57 inline void rotate(node *x){ 58 int t1,t2; 59 node *fa,*gfa; 60 t1=get_parent(x,fa); 61 t2=get_parent(fa,gfa); 62 if ((fa->ch[t1]=x->ch[t1^1])) fa->ch[t1]->fa=fa; 63 x->ch[t1^1]=fa;fa->fa=x;x->fa=gfa; 64 if (t2!=-1) gfa->ch[t2]=x; 65 fa->update();return; 66 } 67 inline void pushdown(node *x){ 68 static node *stack[maxn]; 69 int cnt=0; 70 while(1){ 71 stack[cnt++]=x; 72 node *fa=x->fa; 73 if (!fa || (fa->ch[0]!=x && fa->ch[1]!=x)) break; 74 x=fa; 75 } 76 while(cnt--) stack[cnt]->down(); 77 return; 78 } 79 inline node * splay(node *x){ 80 pushdown(x); 81 while(1){ 82 int t1,t2; 83 node *fa,*gfa; 84 t1=get_parent(x,fa); 85 if(t1==-1) break; 86 t2=get_parent(fa,gfa); 87 if(t2==-1){ 88 rotate(x);break; 89 } else if (t1==t2){ 90 rotate(fa);rotate(x); 91 } else{ 92 rotate(x);rotate(x); 93 } 94 } 95 x->update(); 96 return x; 97 } 98 inline node * access(node *x){ 99 node *ret=NULL; 100 while (x) splay(x)->ch[1]=ret,(ret=x)->update(),x=x->fa; 101 return ret; 102 } 103 inline void makeroot(int x){access(lct+x)->add_rev_tag();} 104 inline void link(int u,int v){ 105 makeroot(u);splay(lct+u)->fa=lct+v;return; 106 } 107 int n,q; 108 int main(){ 109 n=read(); 110 int i; 111 int lim=n<<1; 112 for(i=1;i<=lim;i++) { 113 lct[i]=(node){0,inf,-inf,0,0,0}; 114 } 115 for(i=1;i<n;i++){ 116 int u,v,w; 117 u=read();v=read(); 118 link(u,i+n);link(v,i+n);lct[i+n].add_set_tag(read()); 119 } 120 q=read(); 121 int x,y,c; 122 while(q--){ 123 c=read();x=read();y=read(); 124 if(c==0) makeroot(x+n),access(x+n+lct)->add_set_tag(y); 125 else{ 126 if(x==y){puts("error");continue;} 127 makeroot(x);node*t=access(y+lct); 128 write(t->mx);PAU;write(t->mi);PAU;write(t->sm);ENT; 129 } 130 } 131 return 0; 132 }

?

搜索

復(fù)制

轉(zhuǎn)載于:https://www.cnblogs.com/chxer/p/4525824.html

總結(jié)

以上是生活随笔為你收集整理的COJ 1006 树上操作的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。