bzoj 2243: [SDOI2011]染色
2017-08-16 00:17
302 查看
bzoj 2243: [SDOI2011]染色
树链剖分,线段树题意
给定一棵有n个节点的无根树和m个操作,操作有2类:将节点a到节点b路径上所有点都染成颜色c;
询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),如“112221”由3段组成:“11”、“222”和“1”。
请你写一个程序依次完成这m个操作。
思路
这种东西。。感觉很套路啊,学会了之后根本不难写,顶多是代码太多写丑了需要调。而且能解决的问题也都很套路。。还是我没碰到高级的问题?在树上的修改查询,想到树链剖分。我之前一篇Gym的题解说的挺细,不带修改。这题带修改,也没什么区别。修改时也是跟查询一样,往爸爸上跳,直到跳到重链。
啊。。这题,合并查询结果时要注意一下,比如lres有结果,rres没结果,那么返回lres就行,或者合并时把res的右端点给赋值。
代码
#include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #include<vector> #include<map> #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 #define M(a,b) memset(a,b,sizeof(a)) using namespace std; const int MAXN=100007; const int oo=0x3f3f3f3f; vector<int> G[MAXN]; int Val[MAXN], Hson[MAXN], SonAmount[MAXN], Father[MAXN], Depth[MAXN]; int Dfsnum[MAXN], TreeValue[MAXN], TopOfHeavyChain[MAXN]; int dfscount; void AddEdge(int from, int to) { G[from].push_back(to); G[to].push_back(from); } void dfs1(int n) { SonAmount =1; for(int i=0;i<G .size();i++) { int to=G [i]; if(Depth[to]) continue; Depth[to]=Depth +1; Father[to]=n; dfs1(to); SonAmount +=SonAmount[to]; if(SonAmount[to]>SonAmount[Hson ]) Hson =to; } return; } void dfs2(int n, int prev) { Dfsnum =++dfscount; TreeValue[dfscount]=Val ; TopOfHeavyChain =prev; if(!Hson ) return; dfs2(Hson , prev); for(int i=0;i<G .size();i++) { int to=G [i]; if(to==Hson ||to==Father ) continue; dfs2(to, to); } } struct Stree { int block; int lcol, rcol; int lazy; Stree() { block=0;lcol=rcol=lazy=0; } Stree operator + (const Stree &b)const { Stree res; res.lcol=lcol, res.rcol=b.rcol; if(rcol==b.lcol) res.block=block+b.block-1; else res.block=block+b.block; return res; } }stree[MAXN<<2]; void build(int l, int r, int rt) { if(l==r) { stree[rt].block=1; stree[rt].lcol=stree[rt].rcol=TreeValue[l]; return; } int mid=(l+r)>>1; build(lson), build(rson); stree[rt]=stree[rt<<1]+stree[rt<<1|1]; } void pushdown(int rt) { if(stree[rt].lazy!=0) { int c=stree[rt].lazy;stree[rt].lazy=0; stree[rt<<1].lazy=stree[rt<<1|1].lazy=c; stree[rt<<1].block=stree[rt<<1|1].block=1; stree[rt<<1].lcol=stree[rt<<1|1].lcol=c; stree[rt<<1].rcol=stree[rt<<1|1].rcol=c; } } void update(int L, int R, int c, int l, int r, int rt) { if(L<=l&&r<=R) { stree[rt].block=1; stree[rt].lazy=c; stree[rt].lcol=stree[rt].rcol=c; return; } pushdown(rt); int mid=(l+r)>>1; if(L<=mid) update(L, R, c, lson); if(mid<R) update(L, R, c, rson); stree[rt]=stree[rt<<1]+stree[rt<<1|1]; } Stree query(int L, int R, int l, int r, int rt) { if(L<=l&&r<=R) return stree[rt]; pushdown(rt); int mid=(l+r)>>1; bool tl=0, tr=0; if(R<=mid) return query(L, R, lson); if(mid<L) return query(L, R, rson); return query(L, R, lson)+query(L, R, rson); } void solvequ(int n) { Stree lc, rc; int l, r;scanf("%d%d", &l, &r); int fl=TopOfHeavyChain[l], fr=TopOfHeavyChain[r]; while(fl!=fr) { if(Depth[fl]>Depth[fr]) { lc=query(Dfsnum[fl], Dfsnum[l], 1, n, 1)+lc; l=Father[fl]; fl=TopOfHeavyChain[l]; } else { rc=query(Dfsnum[fr], Dfsnum[r], 1, n, 1)+rc; r=Father[fr]; fr=TopOfHeavyChain[r]; } } if(Depth[l]>Depth[r]) lc=query(Dfsnum[r], Dfsnum[l], 1, n, 1)+lc; else rc=query(Dfsnum[l], Dfsnum[r], 1, n, 1)+rc; swap(lc.lcol, lc.rcol); printf("%d\n", (lc+rc).block); } void solveup(int n) { int l, r;scanf("%d%d", &l, &r); int c;scanf("%d", &c); int fl=TopOfHeavyChain[l], fr=TopOfHeavyChain[r]; while(fl!=fr) { if(Depth[fl]>Depth[fr]) { update(Dfsnum[fl], Dfsnum[l], c, 1, n, 1); l=Father[fl]; fl=TopOfHeavyChain[l]; } else { update(Dfsnum[fr], Dfsnum[r], c, 1, n, 1); r=Father[fr]; fr=TopOfHeavyChain[r]; } } if(Depth[l]>Depth[r]) update(Dfsnum[r], Dfsnum[l], c, 1, n, 1); else update(Dfsnum[l], Dfsnum[r], c, 1, n, 1); } int main() { //freopen("in.txt", "r", stdin); //freopen("ou1.txt", "w", stdout); int n, m; while(scanf("%d%d", &n, &m)==2) { dfscount=0;M(Hson, 0); for(int i=1;i<=n;i++) G[i].clear(); for(int i=1;i<=n;i++) scanf("%d", &Val[i]); for(int i=1;i<n;i++) { int ta, tb;scanf("%d%d", &ta, &tb); AddEdge(ta, tb); } Depth[1]=1;dfs1(1);dfs2(1, 1); build(1, n, 1); while(m--) { char s[10];scanf("%s", s); if(s[0]=='C') solveup(n); else solvequ(n); } } //system("pause"); return 0; }
相关文章推荐
- 【bzoj2243】[SDOI2011]染色
- bzoj 2243:[SDOI2011]染色 树链剖分
- Bzoj 2243: [SDOI2011]染色(树链剖分+线段树)
- bzoj 2243 [SDOI2011]染色(树链剖分,线段树)
- [bzoj2243][SDOI2011]染色
- BZOJ2243: [SDOI2011]染色
- bzoj2243 [SDOI2011]染色
- bzoj 2243: [SDOI2011]染色 树链剖分+线段树
- BZOJ 2243 SDOI2011 染色 树链剖分
- BZOJ2243: [SDOI2011]染色
- BZOJ2243: [SDOI2011]染色(洛谷P2486)
- bzoj2243: [SDOI2011]染色
- BZOJ 2243: [SDOI2011]染色 (树链剖分+线段树合并)
- 【BZOJ2243】【SDOI2011】染色 树链剖分
- BZOJ2243: [SDOI2011]染色
- bzoj2243[SDOI2011]染色 (树剖)
- [SDOI2011][BZOJ2243] 染色|线段树|树链剖分
- Bzoj2243[SDOI2011]染色:树链剖分
- [SDOI2011] [BZOJ2243] 染色 - 树链剖分
- bzoj 2243 [SDOI2011]染色 树剖+线段树