【kd-tree】bzoj4154 [Ipsc2015]Generating Synergy
2015-06-24 09:06
295 查看
区间修改的kd-tree,打标记,下传。
每次询问的时候,从询问点向上找到根,然后依次下传下来,再回答询问。
每次询问的时候,从询问点向上找到根,然后依次下传下来,再回答询问。
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; #define N 100001 #define KD 2 int n,root,m,q,qp[2][KD],fa ,val,delta ; bool dn; struct Node { int ch[2],w,minn[KD],maxx[KD],p[KD],id; void Init() { for(int i=0;i<KD;++i) minn[i]=maxx[i]=p[i]; } }T ; bool operator < (const Node &a,const Node &b){return a.p[dn] < b.p[dn];} inline void pushup(const int &rt) { for(int i=0;i<2;++i) if(T[rt].ch[i]) for(int j=0;j<KD;++j) { T[rt].minn[j]=min(T[rt].minn[j],T[T[rt].ch[i]].minn[j]); T[rt].maxx[j]=max(T[rt].maxx[j],T[T[rt].ch[i]].maxx[j]); } } inline void pushdown(const int &rt) { if(delta[rt]) { T[rt].w=delta[rt]; for(int i=0;i<2;++i) delta[T[rt].ch[i]]=delta[rt]; delta[rt]=0; } } int buildtree(int l=1,int r=n,bool d=0) { dn=d; int m=(l+r>>1); nth_element(T+l,T+m,T+r+1); T[m].Init(); if(l!=m) T[m].ch[0]=buildtree(l,m-1,d^1); if(m!=r) T[m].ch[1]=buildtree(m+1,r,d^1); pushup(m); return m; } void Update(int rt=root) { if(qp[0][0] <= T[rt].minn[0] && T[rt].maxx[0] <= qp[0][1] && qp[1][0] <= T[rt].minn[1] && T[rt].maxx[1] <= qp[1][1]) { delta[rt]=val; return; } pushdown(rt); if(qp[0][0] <= T[rt].p[0] && T[rt].p[0] <= qp[0][1] && qp[1][0] <= T[rt].p[1] && T[rt].p[1] <= qp[1][1]) T[rt].w=val; for(int i=0;i<2;++i) if(T[rt].ch[i] && qp[0][0] <= T[T[rt].ch[i]].maxx[0] && T[T[rt].ch[i]].minn[0] <= qp[0][1] && qp[1][0] <= T[T[rt].ch[i]].maxx[1] && T[T[rt].ch[i]].minn[1] <= qp[1][1]) Update(T[rt].ch[i]); } void Query(int U) { if(fa[U]) Query(fa[U]); pushdown(U); } int zu; int v ,next ,first ,e; void AddEdge(const int &U,const int &V) { v[++e]=V; next[e]=first[U]; first[U]=e; } int dep ,dfn ,dfr ; void dfs(int U) { dfn[U]=++e; T[U].w=1; T[U].p[0]=e; T[U].p[1]=dep[U]; T[U].id=U; for(int i=first[U];i;i=next[i]) { dep[v[i]]=dep[U]+1; dfs(v[i]); } dfr[U]=e; } typedef long long ll; #define MOD 1000000007ll ll ans; int ma ; int main() { // freopen("bzoj4154.in","r",stdin); scanf("%d",&zu); for(;zu;--zu) { int x,dis; scanf("%d%d%d",&n,&m,&q); for(int i=2;i<=n;++i) { scanf("%d",&x); AddEdge(x,i); } e=0; dep[1]=1; dfs(1); buildtree(); root=(1+n>>1); for(int i=1;i<=n;++i) { ma[T[i].id]=i; for(int j=0;j<2;++j) if(T[i].ch[j]) fa[T[i].ch[j]]=i; } for(int i=1;i<=q;++i) { scanf("%d%d%d",&x,&dis,&val); if(!val) { Query(ma[x]); ans=(ans+(ll)i*(ll)T[ma[x]].w%MOD)%MOD; } else { qp[0][0]=dfn[x]; qp[0][1]=dfr[x]; qp[1][0]=dep[x]; qp[1][1]=dep[x]+dis; Update(); } } printf("%lld\n",ans); for(int i=1;i<=n;++i) T[i].ch[0]=T[i].ch[1]=0; memset(delta+1,0,sizeof(int)*n); memset(fa+1,0,sizeof(int)*n); ans=e=0; memset(first+1,0,sizeof(int)*n); } return 0; }
相关文章推荐
- iOS应用开发(五) 视图控制器生命周期
- 架构师速成4.1-幼儿园要学会如何学习(转载自36氪)
- 架构师速成4.1-幼儿园要学会如何学习(转载自36氪) 分类: 架构师速成 2015-06-24 09:05 114人阅读 评论(0) 收藏
- 微软的操作系统中让 32 位支持大于 4GB 的内存。
- linux下查看系统进程占用的句柄数
- Exchange 日常管理八之:部署高可用的邮箱服务器
- Exchange 日常管理八之:部署高可用的邮箱服务器
- OSGEARTH视频教程31讲学习,解决osgEARTH水平看太黑的问题
- 如何将内存中的位图数据绘制在DC上
- Mysql 基于 Amoeba 的 读写分离
- idea的常用快捷键整理(备用)
- Ios应用开发(四)框架及带属性的字符串
- Eclipse配置C/C++开发环境
- 黑马程序员--iOS-OC基本语法
- mac 终端 常用命令
- 刮痧,拔罐加艾灸治好了膝盖痛
- iOS UI 视图
- HDU 1160(FatMouse's Speed)最长不降子序列nlogn+路径记录
- jquery实现鼠标拖拽排序功能
- 关于浏览器网页渲染基本结构图