BZOJ4154——IPSC2015 Generating Synergy
来源:互联网 发布:wpf 数据绑定 编辑:程序博客网 时间:2024/06/02 05:20
题意:AC通道
题解:
这题有个十分巧妙的解法。
因为有子树修改,而又不是整棵子树的修改,直接上dfs序是不行的。
考虑它每次修改的只有子节点,而且有距离限制,我们想到这是与点的深度有关的问题。
于是我们把树上的点抽象到二维平面上,横坐标为其dfs序,纵坐标为其深度,这样每次的修改就对应一个区域的染色操作,这东西用kdtree可以随便搞,弄个lazytag就可以了。
一堆调试用的代码,所以看起来很长。
#include <bits/stdc++.h>//#include <conio.h>using namespace std;typedef long long ll;typedef double db;const int inf=0x3f3f3f3f;int getint(){ int f=1,g=0;char c=getchar(); while(c<'0' || c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0' && c<='9')g=(g<<3)+(g<<1)+c-'0',c=getchar(); return f*g;}const int maxn=100005;const int mod=1000000007;int dim;int n,m;struct node{ int d[2]; int max[2]; int min[2]; int l,r; int tag; int color; int& operator [] (const unsigned int& num) { return d[num]; } bool operator < (const node& no)const { return d[dim]<no.d[dim]; } bool operator == (const node& no)const { return d[0]==no.d[0] && d[1]==no.d[1]; }};node p[maxn];int root;struct Kdtree{ node t[maxn]; #define lc t[x].l #define rc t[x].r #define ls t[t[x].l] #define rs t[t[x].r] void update(int x) { t[x].min[0]=t[x].max[0]=t[x][0]; t[x].min[1]=t[x].max[1]=t[x][1]; if(lc) { t[x].min[0]=min(t[x].min[0],ls.min[0]); t[x].max[0]=max(t[x].max[0],ls.max[0]); t[x].min[1]=min(t[x].min[1],ls.min[1]); t[x].max[1]=max(t[x].max[1],ls.max[1]); } if(rc) { t[x].min[0]=min(t[x].min[0],rs.min[0]); t[x].max[0]=max(t[x].max[0],rs.max[0]); t[x].min[1]=min(t[x].min[1],rs.min[1]); t[x].max[1]=max(t[x].max[1],rs.max[1]); } } void push_down(int x) { if(!x || !t[x].tag)return; t[x].color=t[x].tag; ls.tag=rs.tag=t[x].tag; t[x].tag=0; } #define mid (l+r>>1) int build(int l,int r,int now) { dim=now; nth_element(p+l,p+mid,p+r+1); int x=mid; t[x].color=1; for(int i=0;i<2;i++) { t[x].min[i]=t[x].max[i]=t[x][i]=p[x][i]; } if(l<mid)lc=build(l,mid-1,now^1); if(r>mid)rc=build(mid+1,r,now^1); update(x); return x; } #undef mid node T1,T2; int col; void setcolor(int x) { if(!x)return; push_down(x); if(t[x].min[0]>T2[0] || t[x].max[0]<T1[0] || t[x].min[1]>T2[1] || t[x].max[1]<T1[1])return; if(t[x].min[0]>=T1[0] && t[x].max[0]<=T2[0] && t[x].min[1]>=T1[1] && t[x].max[1]<=T2[1]) { t[x].tag=col; return; } if(t[x][0]>=T1[0] && t[x][0]<=T2[0] && t[x][1]>=T1[1] && t[x][1]<=T2[1])t[x].color=col; setcolor(lc);setcolor(rc); } node T; int getcolor(int x) { push_down(x); if(T[0]<t[x].min[0] || T[0]>t[x].max[0] || T[1]<t[x].min[1] || T[1]>t[x].max[1])return 0; if(t[x]==T)return t[x].color; return getcolor(lc)+getcolor(rc); } void set(int x,int y,int xx,int yy,int co) { T1[0]=x;T1[1]=y; T2[0]=xx;T2[1]=yy; col=co; setcolor(root); } int query(int x,int y) { T[0]=x;T[1]=y; return getcolor(root); } void init() { memset(t,0,sizeof t); memset(p,0,sizeof p); root=0; } void run(int x) { if(!x)return; run(lc); printf("(%d,%d)->(%d,%d):%d(%d)(%d,%d)\n",t[x].min[0],t[x].min[1],t[x].max[0],t[x].max[1],t[x].color,t[x].tag,t[x][0],t[x][1]); run(rc); } #undef lc #undef rc #undef ls #undef rs}kdtree;vector<int> g[maxn];void addedge(int from,int to){ g[from].push_back(to); g[to].push_back(from);}int dep[maxn];int st[maxn];int ed[maxn];int ind;int father[maxn];void dfs(int x){ st[x]=++ind; for(int i=0;i<g[x].size();i++) { int to=g[x][i]; if(father[x]==to)continue; dep[to]=dep[x]+1; dfs(to); } ed[x]=ind;}int main(){// freopen("in.txt","r",stdin); int T=getint(); while(T--) { for(int i=0;i<maxn;i++)g[i].clear(); kdtree.init(); ind=0; n=getint(); int temp=getint(); m=getint(); for(int i=2;i<=n;i++) { father[i]=getint(); addedge(i,father[i]); } dep[1]=1; dfs(1); /* for(int i=1;i<=n;i++) { printf("%d ",st[i]); } puts(""); for(int i=1;i<=n;i++) { printf("%d ",ed[i]); } puts(""); for(int i=1;i<=n;i++) { printf("%d ",dep[i]); } puts(""); */ for(int i=1;i<=n;i++) { p[i][0]=st[i]; p[i][1]=dep[i]; } root=kdtree.build(1,n,0); /* kdtree.run(root); puts(""); getch(); */ int x,y; int opt; ll ans=0; for(int i=1;i<=m;i++) { x=getint(); y=getint(); opt=getint(); if(!opt) { ll t=kdtree.query(st[x],dep[x]); //printf("%d\n",t); ans+=(ll)t*(ll)i; ans%=mod; } else { /* printf("We are painting (%d,%d)->(%d,%d):%d\n",st[x],dep[x],ed[x],dep[x]+y,opt); getch(); */ kdtree.set(st[x],dep[x],ed[x],dep[x]+y,opt); } /* kdtree.run(root); puts(""); getch(); */ } printf("%d\n",ans); } return 0;}
0 0
- BZOJ4154——IPSC2015 Generating Synergy
- 【IPSC2015】【BZOJ4154】Generating Synergy
- [bzoj4154][Ipsc2015]Generating Synergy
- BZOJ4154 [Ipsc2015]Generating Synergy
- BZOJ4154: [Ipsc2015]Generating Synergy
- BZOJ4154:Generating Synergy (KDtree)
- 【BZOJ】4154: [Ipsc2015]Generating Synergy【KD树】
- 4154: [Ipsc2015]Generating Synergy K-D tree
- bzoj 4154: [Ipsc2015]Generating Synergy KDtree
- [Ipsc2015]Generating Synergy K-D tree
- bzoj 4154: [Ipsc2015]Generating Synergy (KD-tree)
- NKOJ 4345 (Ipsc2015)Generating Synergy (DFS序+kd树)
- HYSBZ4154-Generating Synergy
- 【38.05%】【BZOJ 4154】Generating Synergy
- BZOJ 4154(Generating Synergy-kd-tree代替树套树)
- synergy
- synergy
- synergy
- strcpy与memcpy重新实现
- jackson使用
- viewpager动态加载数据
- ogre shadow(阴影)函数笔记
- 第一个Unity项目Hello Unity
- BZOJ4154——IPSC2015 Generating Synergy
- VS2010出现fatal error C1902: 程序数据库管理器不匹配;请检查安装
- Protocol in Objective-C
- jquery 的(function(){});表示什么
- IOS中的ViewController 的loadView、viewDidLoad、viewDidUnload
- idea快捷键
- bootstrap js插件篇——下拉菜单、滚动监测、选项卡
- asp.net mvc4 简单使用Autofac依赖注入小结
- phonegap(cordova) 入门 9----小知识点总结--iOS 状态栏的字体颜色都设置为白色