多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > php教程 > 【BZOJ 3531】 [Sdoi2014]旅行

【BZOJ 3531】 [Sdoi2014]旅行

來源:程序員人生   發布時間:2015-04-14 08:06:40 閱讀次數:2741次

3531: [Sdoi2014]旅行

Time Limit: 20 Sec Memory Limit: 512 MB
Submit: 575 Solved: 303
[Submit][Status][Discuss]
Description

S國有N個城市,編號從1到N。城市間用N⑴條雙向道路連接,滿足
從1個城市動身可以到達其它所有城市。每一個城市信仰不同的宗教,如飛天面條神教、隱形獨角獸教、絕地教都是常見的信仰。為了方便,我們用不同的正整數代表各種宗教, S國的居民常常旅行。旅行時他們總會走最短路,并且為了不麻煩,只在信仰和他們相同的城市留宿。固然旅程的終點也是信仰與他相同的城市。S國政府為每一個城市標定了不同的旅行評級,旅行者們常會記下途中(包括出發點和終點)留宿過的城市的評級總和或最大值。
在S國的歷史上常會產生以下幾種事件:
”CC x c”:城市x的居民全部改信了c教;
”CW x w”:城市x的評級調劑為w;
”QS x y”:1位旅行者從城市x動身,到城市y,并記下了途中留宿過的城市的評級總和;
”QM x y”:1位旅行者從城市x動身,到城市y,并記下了途中留宿過
的城市的評級最大值。
由于年代久遠,旅行者記下的數字已遺失了,但記錄開始之前每座城市的信仰與評級,還有事件記錄本身是完好的。請根據這些信息,還原旅行者記下的數字。 為了方便,我們認為事件之間的間隔足夠長,以致在任意1次旅行中,所有城市的評級和信仰保持不變。

Input

輸入的第1行包括整數N,Q順次表示城市數和事件數。
接下來N行,第i+l行兩個整數Wi,Ci順次表示記錄開始之前,城市i的

評級和信仰。
接下來N⑴行每行兩個整數x,y表示1條雙向道路。
接下來Q行,每行1個操作,格式如上所述。

Output

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

Sample Input

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

Sample Output

8

9

11

3

HINT

N,Q < =10^5 , C < =10^5

數據保證對所有QS和QM事件,出發點和終點城市的信仰相同;在任意時

刻,城市的評級總是不大于10^4的正整數,且宗教值不大于C。

Source

Round 1 Day 1

樹鏈剖分+動態開結點。

如果沒有同1個信仰的限制就是裸的樹鏈剖分了。

我們可以對每個信仰都建1棵線段樹,但是普通方法建線段樹就會MLE。

因此我們采取動態開結點的辦法:
假定n=5,我們要在線段樹中加入1個id=4的人,那末我們只需要開”4⑸”這個結點,而不用開”1⑶”的結點,由于開了也沒用。

在最壞情況下,每一個人都屬于不同的信仰,我們對每一個信仰開1棵線段樹,也只需要nlogn個節點了~

然后就是裸的樹鏈剖分了。

#include <iostream> #include <algorithm> #include <cmath> #include <cstring> #include <cstdio> #include <cstdlib> #define M 100005 using namespace std; int id[M],n,now,q,h[M],tote=0,tot=0,fa[M],size[M],son[M],dep[M],top[M]; int root[M]; struct data { int c,w; }a[M]; struct Segtree { int l,r,ma,sum; }t[8000005]; struct edge { int y,ne; }e[M*2]; void Addedge(int x,int y) { e[++tote].y=y; e[tote].ne=h[x]; h[x]=tote; } void dfs1(int x,int f,int de) { dep[x]=de; size[x]=1; son[x]=0; fa[x]=f; for (int i=h[x];i;i=e[i].ne) { int y=e[i].y; if (y==f) continue; dfs1(y,x,de+1); size[x]+=size[y]; if (size[son[x]]<size[y]) son[x]=y; } } void dfs2(int x,int tp) { top[x]=tp; id[x]=++now; if (son[x]) dfs2(son[x],tp); for (int i=h[x];i;i=e[i].ne) { int y=e[i].y; if (y==son[x]||y==fa[x]) continue; dfs2(y,y); } } void Push_up(int x) { t[x].ma=max(t[t[x].l].ma,t[t[x].r].ma); t[x].sum=t[t[x].l].sum+t[t[x].r].sum; } void Build(int &x,int l,int r,int p,int v) { if (!x) x=++tot; if (l==r) { t[x].sum=t[x].ma=v; return; } int m=(l+r)>>1; if (p<=m) Build(t[x].l,l,m,p,v); else Build(t[x].r,m+1,r,p,v); Push_up(x); } int Getsum(int x,int lt,int rt,int l,int r) { if (!x) return 0; if (l<=lt&&rt<=r) return t[x].sum; int m=(lt+rt)>>1; int ans=0; if (l<=m) ans+=Getsum(t[x].l,lt,m,l,r); if (r>m) ans+=Getsum(t[x].r,m+1,rt,l,r); return ans; } int Qsum(int x,int y) { int C=a[x].c; int tp1=top[x],tp2=top[y]; int ans=0; while (tp1!=tp2) { if (dep[tp1]<dep[tp2]) swap(tp1,tp2),swap(x,y); ans+=Getsum(root[C],1,n,id[tp1],id[x]); x=fa[tp1]; tp1=top[x]; } if (x==y) return ans+(a[x].c==C)*a[x].w; if (dep[x]>dep[y]) swap(x,y); ans+=Getsum(root[C],1,n,id[x],id[y]); return ans; } int Getmax(int x,int lt,int rt,int l,int r) { if (!x) return 0; if (l<=lt&&rt<=r) return t[x].ma; int m=(lt+rt)>>1; int ans=0; if (l<=m) ans=Getmax(t[x].l,lt,m,l,r); if (r>m) ans=max(ans,Getmax(t[x].r,m+1,rt,l,r)); return ans; } int Qmax(int x,int y) { int C=a[x].c; int tp1=top[x],tp2=top[y]; int ans=0; while (tp1!=tp2) { if (dep[tp1]<dep[tp2]) swap(tp1,tp2),swap(x,y); ans=max(ans,Getmax(root[C],1,n,id[tp1],id[x])); x=fa[tp1]; tp1=top[x]; } if (x==y) return max(ans,(a[x].c==C)*a[x].w); if (dep[x]>dep[y]) swap(x,y); ans=max(ans,Getmax(root[C],1,n,id[x],id[y])); return ans; } int main() { now=0; scanf("%d%d",&n,&q); for (int i=1;i<=n;i++) scanf("%d%d",&a[i].w,&a[i].c); for (int i=1;i<n;i++) { int x,y; scanf("%d%d",&x,&y); Addedge(x,y); Addedge(y,x); } dfs1(1,0,1); dfs2(1,0); for (int i=1;i<=n;i++) Build(root[a[i].c],1,n,id[i],a[i].w); while (q--) { char s[5]; int x,y; scanf("%s",s); scanf("%d%d",&x,&y); if (s[0]=='C') { if (s[1]=='C') { Build(root[a[x].c],1,n,id[x],0); a[x].c=y; Build(root[a[x].c],1,n,id[x],a[x].w); } else { a[x].w=y; Build(root[a[x].c],1,n,id[x],a[x].w); } } else { if (s[1]=='S') printf("%d ",Qsum(x,y)); else printf("%d ",Qmax(x,y)); } } return 0; }

這里寫圖片描述
感悟:
這道題調了好久,由于樹鏈剖分返回的時候沒有判斷最后1個點是不是是與出發點屬于同1個信仰的。。

生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 国产三级视频 | 亚洲国产精品尤物yw在线观看 | 一区二区三区在线视频播放 | 亚洲人成网站在线观看播放 | 女人一级毛片免费观看 | 欧美乱大交xxxx | 欧美一级日韩一级 | 精品在线视频播放 | 成人在线观看不卡 | 午夜爱爱片 | 性生活视频网 | 4虎1515hh永久免费 | 美国福利视频 | 日本三级s级在线播放 | 欧美综合伊人久久 | 一区二区三区在线免费观看视频 | 欧美成人午夜视频在线观看 | 手机看片手机在线看片 | 午夜影院在线观看免费 | 亚洲精品一区二区乱码在线观看 | 中文字幕最新在线 | 精品一区二区三区在线观看l | 日本一二三区视频 | 男女很舒服爽视频免费 | 欧美videos另类极品 | 2020久久精品亚洲热综合 | 欧美人马交 | 中文字幕第一页在线 | 武则天a级在线观看 | 黑人日批| 多人做人爱视频大全在线观看 | 日本一区二区高清 | 欧美最新一区二区三区四区 | 日本美女影院 | 最新欧美18videosex性欧美 | 欧美xx性| 国产日韩欧美精品一区二区三区 | 韩国三级hd中文字幕一男多女 | 国产91精品高清一区二区三区 | free日韩性公交车上xxhd | 亚洲国产第一 |