bzoj3531 [Sdoi2014]旅行 【树链剖分+线段树动态开点】
来源:互联网 发布:九阴真经买淘宝礼包 编辑:程序博客网 时间:2024/05/17 01:58
链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3531
题意:中文题
分析:由于是在树上求某一条路径(u,v)的值,很容易想到用树链剖分求,但是每次求的路径只需要与(u,v)相同颜色的点的值,不能直接用线段树统一维护。
我们考虑每种颜色都建一颗线段树,那么直接维护相应颜色上的值就行了,但是这样空间是O(n*n),如果我们建n棵空树,树的大小都是0,然后动态将对应颜色的点
插入,由于操作数只有1e5,所以所有线段树的叶子点加起来不超过O(2*n),线段树的大小O(8*n) 空间就够了。
代码:
#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<string>#include<vector>#include<queue>#include<cmath>#include<stack>#include<set>#include<map>#define INF 0x3f3f3f3f#define Mn 100010#define Mm 2000005#define mod 1000000007#define CLR(a,b) memset((a),(b),sizeof((a)))#define CLRS(a,b,Size) memset((a),(b),sizeof((a[0]))*(Size+1))#define CPY(a,b) memcpy ((a), (b), sizeof((a)))#pragma comment(linker, "/STACK:102400000,102400000")#define ul u<<1#define ur (u<<1)|1using namespace std;typedef long long ll;int read() { char c; int ans=0,f=1;c=getchar(); while(c<'0'|c>'9') {if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9') {ans=ans*10+c-'0';c=getchar();} return ans*f;}struct edge { int v,next;}e[Mm];int tot,head[Mn];void addedge(int u,int v) { e[tot].v=v; e[tot].next=head[u]; head[u]=tot++;}int w[Mn],c[Mn];int siz[Mn],son[Mn],top[Mn],deep[Mn],pre[Mn];void dfs(int u,int fa,int de) { siz[u]=1;deep[u]=de;pre[u]=fa; for(int i=head[u];~i;i=e[i].next) { if(e[i].v==fa) continue; dfs(e[i].v,u,de+1); if(son[u]==-1||siz[e[i].v]>siz[son[u]]) son[u]=e[i].v; siz[u]+=siz[e[i].v]; }}int len,inTree[Mn],id[Mn];void DFS(int u,int tp) { top[u]=tp; inTree[u]=++len; id[inTree[u]]=u; if(son[u]==-1) return ; else DFS(son[u],tp); for(int i=head[u];~i;i=e[i].next) if(son[u]!=e[i].v&&e[i].v!=pre[u]) DFS(e[i].v,e[i].v);}int root[Mn],ls[Mn*50],rs[Mn*50],cnt;int sum[Mn*50],maxx[Mn*50];void pushUp(int node) { sum[node]=sum[ls[node]]+sum[rs[node]]; maxx[node]=max(maxx[ls[node]],maxx[rs[node]]);}void update(int &node,int l,int r,int pos,int x) { if(!node) node=++cnt; if(l==r) { maxx[node]=sum[node]=x; return ; } int mid=(l+r)>>1; if(pos<=mid) update(ls[node],l,mid,pos,x); else update(rs[node],mid+1,r,pos,x); pushUp(node);}int ask(int node,int s,int t,int l,int r,int op) { if(!node) return 0; if(s<=l&&t>=r) { if(op) return maxx[node]; else return sum[node]; } int r1=0,r2=0; int mid=(l+r)>>1; if(s<=mid) r1=ask(ls[node],s,t,l,mid,op); if(t>mid) r2=ask(rs[node],s,t,mid+1,r,op); if(op) return max(r1,r2); else return r1+r2;}int query(int u,int v,int op) { int ans=0,x,C=c[u]; while(top[u]!=top[v]) { if(deep[top[u]]<deep[top[v]]) swap(u,v); x=ask(root[C],inTree[top[u]],inTree[u],1,len,op); if(op) ans=max(ans,x); else ans+=x; u=pre[top[u]]; } if(deep[u]>deep[v]) swap(u,v); x=ask(root[C],inTree[u],inTree[v],1,len,op); if(op) ans=max(ans,x); else ans+=x; return ans;}void init() { tot=0,len=0;cnt=0; CLR(head,-1); CLR(son,-1);}int main() { init(); int n=read(),q=read(); for(int i=1;i<=n;i++) w[i]=read(),c[i]=read(); for(int i=1;i<n;i++) { int u=read(),v=read(); addedge(u,v); addedge(v,u); } dfs(1,0,0); DFS(1,1); for(int i=1;i<=n;i++) update(root[c[id[i]]],1,len,i,w[id[i]]); char k[10]; while(q--) { scanf("%s",k); int x=read(),y=read(); if(k[1]=='C') { update(root[c[x]],1,len,inTree[x],0); update(root[y],1,len,inTree[x],w[x]); c[x]=y; } else if(k[1]=='S') { printf("%d\n",query(x,y,0)); } else if(k[1]=='W'){ update(root[c[x]],1,len,inTree[x],y); w[x]=y; } else if(k[1]=='M') { printf("%d\n",query(x,y,1)); } } return 0;}
0 0
- bzoj3531 [Sdoi2014]旅行 【树链剖分+线段树动态开点】
- [BZOJ3531][SDOI2014]旅行(链剖+线段树动态开点)
- 【bzoj3531】[Sdoi2014]旅行 动态开点的线段树
- bzoj3531 [Sdoi2014]旅行 树链剖分 线段树
- Bzoj3531:[Sdoi2014]旅行:树链剖分+动态开点线段树
- bzoj3531 [Sdoi2014]旅行(树链剖分+动态开点线段树)
- [BZOJ3531][SDOI2014]旅行(树剖+线段树)
- bzoj3531 [Sdoi2014]旅行 树链剖分+动态开线段树
- 【BZOJ3531】【Sdoi2014】旅行 树链剖分。
- [bzoj3531][Sdoi2014]旅行 树链剖分
- 【bzoj3513】【SDOI2014】【旅行】【树链剖分+动态开点】
- [BZOJ3531] SDOI2014 树链剖分+动态开点线段树
- BZOJ3531 [Sdoi2014]旅行
- [BZOJ3531]SDOI2014旅行
- 【SDOI2014】【BZOJ3531】旅行
- bzoj3531【SDOI2014】旅行
- [BZOJ3531] [SDOI2014] 旅行
- [bzoj3531][SDOI2014]旅行
- Java项目(struts2框架)
- 安卓广播
- POJ 2632 Crashing Robots 机器人模拟
- 欢迎使用CSDN-markdown编辑器
- 1096. Consecutive Factors (20)
- bzoj3531 [Sdoi2014]旅行 【树链剖分+线段树动态开点】
- 【oracle】查询表的相关信息
- 博客初尝试
- 经典第五章例5.1 UVa 10474 Where is the Marble?(排序与检索)
- Spark与Flink:对比与分析
- block的底层实现(二)
- 重绘与重排
- 给创业码农的话--如何提升开发效率
- FPGA笔记(十一)—FPGA引脚验证