日本搞逼视频_黄色一级片免费在线观看_色99久久_性明星video另类hd_欧美77_综合在线视频

國內(nèi)最全I(xiàn)T社區(qū)平臺(tái) 聯(lián)系我們 | 收藏本站
阿里云優(yōu)惠2
您當(dāng)前位置:首頁 > php開源 > php教程 > 【BZOJ 3531】 [Sdoi2014]旅行

【BZOJ 3531】 [Sdoi2014]旅行

來源:程序員人生   發(fā)布時(shí)間:2015-04-14 08:06:40 閱讀次數(shù):2748次

3531: [Sdoi2014]旅行

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

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

Input

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

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

Output

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

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

數(shù)據(jù)保證對所有QS和QM事件,出發(fā)點(diǎn)和終點(diǎn)城市的信仰相同;在任意時(shí)

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

Source

Round 1 Day 1

樹鏈剖分+動(dòng)態(tài)開結(jié)點(diǎn)。

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

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

因此我們采取動(dòng)態(tài)開結(jié)點(diǎn)的辦法:
假定n=5,我們要在線段樹中加入1個(gè)id=4的人,那末我們只需要開”4⑸”這個(gè)結(jié)點(diǎn),而不用開”1⑶”的結(jié)點(diǎn),由于開了也沒用。

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

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

#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; }

這里寫圖片描述
感悟:
這道題調(diào)了好久,由于樹鏈剖分返回的時(shí)候沒有判斷最后1個(gè)點(diǎn)是不是是與出發(fā)點(diǎn)屬于同1個(gè)信仰的。。

生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈(zèng)
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關(guān)閉
程序員人生
主站蜘蛛池模板: 婷婷成人精品视频在线观看 | 天堂аⅴ在线最新版在线 | 99精品视频免费观看 | 国产精品免费一区二区三区四区 | 亚洲国产一区二区三区, | 99精品视频一区二区三区 | 天堂蜜桃一区二区三区 | 日韩精品免费一区二区夜夜嗨 | 日本天堂在线 | 欧美一区二区三区免费看 | 日韩精品网站 | 国产乱色 | 日本精品久久久久久久 | 色在线视频 | 国产精品久久久久一区二区三区共 | 国产精品国产精品国产专区不卡 | 中文字幕国产 | 成人夜晚看av | 91精品一区二区三区蜜桃 | 美女视频黄免费的 | 日韩欧美精品一区二区三区经典 | 久久国产精品一区 | 性生生活大片免费看视频 | 国产精品久久综合 | 99在线视频免费观看 | 精品一区二区电影 | 久久久精品免费视频 | 特黄一级大片 | 午夜久久久久久久久久一区二区 | 国产精品久久久久久久久久久久冷 | www一区二区三区 | 在线观看成人av | 久久久久国产亚洲日本 | 欧美激情在线看 | 国产视频1区 | 精品视频免费观看 | 精品av天堂毛片久久久借种 | 激情av在线播放 | 国产在线日韩 | 国产精品国产三级国产普通话三级 | 91精品国产日韩91久久久久久 |