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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

LOJ2195 旅行

發布時間:2023/12/10 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 LOJ2195 旅行 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

LOJ2195 旅行

題目描述
S 國有 N 個城市,編號從 1 到 N。城市間用 N-1 條雙向道路連接,滿足從一個城市出發可以到達其它所有城市。每個城市信仰不同的宗教,如飛天面條神教、隱形獨角獸教、絕地教都是常見的信仰。為了方便,我們用不同的正整數代表各種宗教,S 國境內總共有 c 種不同的宗教。

S 國的居民常常旅行。旅行時他們總會走最短路,并且為了避免麻煩,只在信仰和他們相同的城市留宿。當然旅程的終點也是信仰與他相同的城市。S 國政府為每個城市標定了不同的旅行評級,旅行者們常會記下途中(包括起點和終點)留宿過的城市的評級總和或最大值。

在 S 國的歷史上常會發生以下幾種事件:

CC x c:城市 x 的居民全體改信了 c 教;
CW x w:城市 x 的評級調整為 w;
QS x y:一位旅行者從城市 x 出發,到城市 y,并記下了途中留宿過的城市的評級總和;
QM x y:一位旅行者從城市 x 出發,到城市 y,并記下了途中留宿過的城市的評級最大值。
由于年代久遠,旅行者記下的數字已經遺失了,但記錄開始之前每座城市的信仰與評級,還有事件記錄本身是完好的。請根據這些信息,還原旅行者記下的數字。
為了方便,我們認為事件之間的間隔足夠長,以致在任意一次旅行中,所有城市的評級和信仰保持不變。

輸入格式
輸入的第一行包含整數 N,Q 依次表示城市數和事件數。
接下來 N 行,第 i+1 行兩個整數 Wi?,Ci? 依次表示記錄開始之前,城市 i 的評級和信仰。
接下來 N-1 行每行兩個整數 x,y 表示一條雙向道路。
接下來 Q 行,每行一個操作,格式如上所述。

輸出格式
對每個 QS 和 QM 事件,輸出一行,表示旅行者記下的數字。

樣例
樣例輸入
5 6
3 1
2 3
1 2
3 3
5 1
1 2
1 3
3 4
3 5
QS 1 5
CC 3 1
QS 1 5
CW 3 3
QS 1 5
QM 2 4
樣例輸出
8
9
1
3
數據范圍與提示
對所有的數據,N,Q≤10^5, C≤10^5,對所有 QS 和 QM 事件,起點和終點城市的信仰相同;在任意時刻,城市的評級總是不大于 10^4 的正整數,且宗教值不大于 c。

_________________________________________________________________________________________

樹鏈剖分,單點修改,求和。

但是由于只對對應的點(信奉相同的宗教)的點求和,而宗教的種類太多,每個線段樹的點不能為10^5個點,所以要動態開點。

第一次寫動態開點線段樹,但過去用指針寫過線段樹,所以感覺不算難。

所謂動態開點,就是用不到的點先不要建點,只把對應的點建立,這樣每次建一個點只需要建一條鏈(長logn)就可以了,不用的點先不用建。

其他的和普通線段樹一樣。

_________________________________________________________________________________________

1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef int ll; 4 const ll maxn=1e5+10; 5 ll n,m; 6 struct edge 7 { 8 int u,v,nxt; 9 }e[maxn<<1]; 10 ll head[maxn],js; 11 void addage(ll u,ll v) 12 { 13 e[++js].u=u;e[js].v=v; 14 e[js].nxt=head[u];head[u]=js; 15 } 16 ll w[maxn],c[maxn]; 17 ll dep[maxn],fat[maxn],siz[maxn],son[maxn]; 18 void dfs(ll u,ll fa) 19 { 20 dep[u]=dep[fa]+1; 21 fat[u]=fa; 22 siz[u]=1; 23 for(ll i=head[u];i;i=e[i].nxt) 24 { 25 ll v=e[i].v; 26 if(v==fa)continue; 27 dfs(v,u); 28 siz[u]+=siz[v]; 29 if(!son[u] || siz[son[u]]<siz[v])son[u]=v; 30 } 31 } 32 ll p,pos[maxn],fos[maxn],top[maxn]; 33 void getpos(ll u,ll fa) 34 { 35 pos[u]=++p; 36 fos[p]=u; 37 top[u]=fa; 38 if(!son[u])return ; 39 getpos(son[u],fa); 40 for(ll i=head[u];i;i=e[i].nxt) 41 { 42 ll v=e[i].v; 43 if(v!=fat[u] && v!=son[u])getpos(v,v); 44 } 45 } 46 struct node 47 { 48 int lc,rc,sm,mx; 49 }t[2001000]; 50 int rt[maxn],cnt; 51 void update(ll cur) 52 { 53 t[cur].sm=t[t[cur].lc].sm+t[t[cur].rc].sm; 54 t[cur].mx=max(t[t[cur].lc].mx,t[t[cur].rc].mx); 55 } 56 void change(ll & cur,ll l,ll r,ll p,ll x) 57 { 58 if(!cur)cur=++cnt; 59 if(l==r) 60 { 61 t[cur].sm=t[cur].mx=x; 62 return ; 63 } 64 ll mid=(l+r)>>1; 65 if(p<=mid)change(t[cur].lc,l,mid,p,x); 66 else change(t[cur].rc,mid+1,r,p,x); 67 update(cur); 68 } 69 ll SUM,MAX; 70 void query(ll cur,ll l,ll r,ll ql,ll qr) 71 { 72 if(!cur)return ; 73 if(ql<=l && r<=qr) 74 { 75 SUM+=t[cur].sm; 76 MAX=max(MAX,t[cur].mx); 77 return ; 78 } 79 ll mid=(l+r)>>1; 80 if(ql<=mid)query(t[cur].lc,l,mid,ql,qr); 81 if(mid<qr)query(t[cur].rc,mid+1,r,ql,qr); 82 } 83 void ask(ll u,ll v) 84 { 85 SUM=0;MAX=0; 86 ll cl=c[u]; 87 ll tpu=top[u],tpv=top[v]; 88 while(tpu!=tpv) 89 { 90 if(dep[tpu]<dep[tpv]) 91 { 92 swap(u,v); 93 swap(tpu,tpv); 94 } 95 query(rt[cl],1,n,pos[tpu],pos[u]); 96 u=fat[tpu];tpu=top[u]; 97 } 98 if(dep[u]>dep[v])swap(u,v); 99 query(rt[cl],1,n,pos[u],pos[v]); 100 } 101 int main() 102 { 103 scanf("%d%d",&n,&m); 104 for(ll i=1;i<=n;++i)scanf("%d%d",w+i,c+i); 105 for(ll u,v,i=1;i<n;++i) 106 { 107 scanf("%d%d",&u,&v); 108 addage(u,v);addage(v,u); 109 } 110 dfs(1,0); 111 getpos(1,1); 112 for(ll i=1;i<=n;++i)change(rt[c[i]],1,n,pos[i],w[i]); 113 char s[4]; 114 ll u,v; 115 while(m--) 116 { 117 scanf("%s%d%d",s,&u,&v); 118 if(s[1]=='W') 119 { 120 w[u]=v; 121 change(rt[c[u]],1,n,pos[u],v); 122 } 123 else if(s[1]=='C') 124 { 125 change(rt[c[u]],1,n,pos[u],0); 126 c[u]=v; 127 change(rt[c[u]],1,n,pos[u],w[u]); 128 } 129 else if(s[1]=='S') 130 { 131 ask(u,v); 132 printf("%d\n",SUM); 133 } 134 else 135 { 136 ask(u,v); 137 printf("%d\n",MAX); 138 } 139 } 140 return 0; 141 } View Code

?

轉載于:https://www.cnblogs.com/gryzy/p/10479157.html

總結

以上是生活随笔為你收集整理的LOJ2195 旅行的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。