Hdu 5221 Occupation
来源:互联网 发布:airdroid windows 编辑:程序博客网 时间:2024/06/05 09:16
算是一个简单的树剖+线段树(不过话说回来树剖也是经常和线段树一起(这个题应该叫做线段树在树上的简单应用(Orz
感觉自己的线段树(特别是区间更新这个地方)还是很不熟练
(观看下文需要一些简单的线段树知识,包括但不限于线段树的定义)
如果不考虑树上的部分的话,这个题要求我们维护一个区间,其中区间中的每一个点都有一个标记和一个value,刚开始的时候,标记都是false
1 将区间[L,R]上所有没有标记的点都标记上
2 将u这个点的标记取消掉
3 询问区间[1,n]上被标记的所有点的权值和
(显然这个题要用到lazy标记(这不是废话吗,线段树什么区间更新的题不用lazy标记的(╯‵□′)╯︵┻━┻
定义lazy[o]==1时表示这个节点的区间是全部被标记的,这个节点的val就是区间和(也就是他的子节点的状态我们都能知道,虽然子节点的val和lazy是不定的,但是会被这一次操作覆盖)我们不知道是不是全部被标记的时候,lazy[o]都为0
随手维护一下前缀和(sum)
操作1好像就变得很简单了
我们只要在当前的区间被标记的区间完全覆盖的时候,把当前的lazy变成1,val[o]=sum[r]-sum[l-1]
然后看操作2
单点更新还是很简单的嗯
唯一需要注意的是如果在更新的路上碰到lazy[o]==1的情况,把这个状态push下去
然后在更新完之后维护一下就好
3的话就是根节点的val了(因为我们每次update之后都维护到了根节点
线段树的部分还是很简单的
然而有眼尖的同学会问,这个题不是要标记一个子树吗QAQ,子树怎么做呀,树链剖分好像不能处理子树的情况啊QAQQQQ
咳咳,仔细回忆一下,是不是有一个神奇的性质(并不),一个子树的dfs序是连续的!
(⊙v⊙)
还有什么问题吗
感觉自己的线段树(特别是区间更新这个地方)还是很不熟练
(观看下文需要一些简单的线段树知识,包括但不限于线段树的定义)
如果不考虑树上的部分的话,这个题要求我们维护一个区间,其中区间中的每一个点都有一个标记和一个value,刚开始的时候,标记都是false
1 将区间[L,R]上所有没有标记的点都标记上
2 将u这个点的标记取消掉
3 询问区间[1,n]上被标记的所有点的权值和
(显然这个题要用到lazy标记(这不是废话吗,线段树什么区间更新的题不用lazy标记的(╯‵□′)╯︵┻━┻
定义lazy[o]==1时表示这个节点的区间是全部被标记的,这个节点的val就是区间和(也就是他的子节点的状态我们都能知道,虽然子节点的val和lazy是不定的,但是会被这一次操作覆盖)我们不知道是不是全部被标记的时候,lazy[o]都为0
随手维护一下前缀和(sum)
操作1好像就变得很简单了
我们只要在当前的区间被标记的区间完全覆盖的时候,把当前的lazy变成1,val[o]=sum[r]-sum[l-1]
然后看操作2
单点更新还是很简单的嗯
唯一需要注意的是如果在更新的路上碰到lazy[o]==1的情况,把这个状态push下去
然后在更新完之后维护一下就好
3的话就是根节点的val了(因为我们每次update之后都维护到了根节点
线段树的部分还是很简单的
然而有眼尖的同学会问,这个题不是要标记一个子树吗QAQ,子树怎么做呀,树链剖分好像不能处理子树的情况啊QAQQQQ
咳咳,仔细回忆一下,是不是有一个神奇的性质(并不),一个子树的dfs序是连续的!
(⊙v⊙)
还有什么问题吗
-------------------------我是代码的分割线-------------------
#include<cstdio>#include<cstring>#include<vector>#include<algorithm>using namespace std;#pragma comment(linker, "/STACK:102400000,102400000")const int maxn = 112345;#define lson o<<1,l,m#define rson o<<1|1,m+1,r#define Mid int m = (l+r)>>1#define root 1,1,n#define Now int o,int l,int r#define LL long longint arr[maxn];int aar[maxn];LL sum[maxn];int lazy[maxn*4];LL val[maxn*4];void sinit(int n){ memset(lazy,0,sizeof(lazy)); memset(val,0,sizeof(val)); sum[0]=0; for(int i=1;i<=n;i++){ sum[i]=sum[i-1]+arr[i]; }}void maintain(Now){ lazy[o]=1; val[o]=sum[r]-sum[l-1];}void update(Now,int ul,int ur){ if(ul<=l && r<=ur){ maintain(o,l,r); return; } Mid; if(lazy[o]==1){ return; } if(ul<=m) update(lson,ul,ur); if(m+1<=ur) update(rson,ul,ur); val[o]=val[o<<1]+val[o<<1|1];}void update(Now,int pos){ // printf("pos = %d\n",pos); if(l==r){ lazy[o]=val[o]=0; return; } Mid; if(lazy[o]==1){ lazy[o]=0; maintain(lson); maintain(rson); } if(pos<=m) update(lson,pos); else update(rson,pos); val[o]=val[o<<1]+val[o<<1|1];}vector<int> edge[maxn];void init(int n){ for(int i=0;i<=n;i++) edge[i].resize(0);}void Link(int st,int ed){ edge[st].push_back(ed); edge[ed].push_back(st);}int fa[maxn],son[maxn],tid[maxn],siz[maxn],top[maxn],deep[maxn];int _cnt;void dffs(int st,int Fa,int Deep){ deep[st]=Deep,son[st]=-1,siz[st]=1,fa[st]=Fa; for(auto & x:edge[st]){ if(x!=Fa){ dffs(x,st,Deep+1); siz[st]+=siz[x]; if(son[st]==-1 || siz[son[st]]<siz[x]) son[st]=x; } }}void dfss(int st,int Top){ tid[st]=_cnt++,top[st]=Top; if(son[st]!=-1) dfss(son[st],Top); for(auto & x:edge[st]){ if(x!=fa[st] && x!=son[st]){ dfss(x,x); } }}void tinit(){ _cnt=1; dffs(1,0,1); dfss(1,1);}void UPD(int x,int y,int n){ int tx = top[x],ty=top[y]; while(tx!=ty){ if(deep[tx] > deep[ty]){ // up x update(root,tid[tx],tid[x]); x=fa[tx],tx=top[x]; } else{ update(root,tid[ty],tid[y]); y=fa[ty],ty=top[y]; } // printf("x = %d y = %d\n",x,y); } if(deep[x]>deep[y]){ update(root,tid[y],tid[x]); } else{ update(root,tid[x],tid[y]); }}void UPD(int x,int n){ int id = tid[x]; int size = siz[x]; update(root,id,id+size-1);}int main(){ int n,m; int T; scanf("%d",&T); while(T-- && ~scanf("%d",&n)){ for(int i=1;i<=n;i++) scanf("%d",&aar[i]); int u,v; init(n); for(int i=1;i<n;i++){ scanf("%d %d",&u,&v); Link(u,v); } tinit(); for(int i=1;i<=n;i++){ arr[tid[i]]=aar[i]; }// for(int i=1;i<=n;i++)// printf(i<n?"%d ":"%d\n",tid[i]);// for(int i=1;i<=n;i++)// printf(i<n?"%d ":"%d\n",top[i]); sinit(n); scanf("%d",&m); int ord; while(m--){ scanf("%d",&ord); if(ord==1){ scanf("%d %d",&u,&v); UPD(u,v,n); } else if(ord==2){ scanf("%d",&u); update(root,tid[u]); } else{ scanf("%d",&u); UPD(u,n); } printf("%lld\n",val[1]); } } return 0;}/*1101 2 3 4 5 6 7 8 9 101 21 32 42 55 95 103 63 73 861 10 41 9 72 53 42 41 6 10155 5 5 5 51 21 31 41 5100863 11008621 101 210086*/
0 0
- 【HDU】5221 Occupation【树链剖分】
- hdu 5221 Occupation
- HDU 5221 Occupation
- Hdu 5221 Occupation
- hdu 5221 Occupation(树链剖分)
- HDU 5221 Occupation dfs序版树链剖分
- HDU 5221 Occupation(树链剖分)
- HDU 5221 Occupation(树链剖分)
- 【HDU 5221】 Occupation 【树链剖分+线段树】
- hdu 5221 Occupation (树剖+线段树)
- "BestCoder"杯中国大学生程序设计冠军赛 HDU 5221 Occupation
- 树链剖分 - hdu5221 Occupation
- HDU5221 Occupation【树链剖分+线段树】
- HDU 5221 树链剖分
- hdu
- hdu
- HDU
- hdu ()
- 2015年工作与学习总结(2015-07-10 22:44、2015-12-01 11:39、2016-1-18 22:44)
- Fragment Transactions和Activity状态丢失
- Android源码--安装应用程序
- 用zabbix 监控 oracle
- Knockout应用开发指南(完整版) 目录索引
- Hdu 5221 Occupation
- Windows双系统下卸载Linux
- 【转】在浮躁的互联网时代,我们该怎么做?
- vc中读取wav文件的时长和文件播放的几种方式
- 3D引擎:Horde3D:Cocos 和 Horde3D渲染部分的设计比较
- 【C++】基础知识—对C语言的加强
- 虚拟键码对照表
- 收集了几个h5案例 与大家分享一下
- iOS 电话 短信 邮件 详解