zoukankan      html  css  js  c++  java
  • BZOJ_4154_[Ipsc2015]Generating Synergy_KDTree

    BZOJ_4154_[Ipsc2015]Generating Synergy_KDTree

    Description

    给定一棵以1为根的有根树,初始所有节点颜色为1,每次将距离节点a不超过l的a的子节点染成c,或询问点a的颜色

    Input

    第一行一个数T,表示数据组数
    接下来每组数据的第一行三个数n,c,q表示结点个数,颜色数和操作数
    接下来一行n-1个数描述2..n的父节点
    接下来q行每行三个数a,l,c
    若c为0,表示询问a的颜色
    否则将距离a不超过l的a的子节点染成c

    Output

    设当前是第i个操作,y_i为本次询问的答案(若本次操作是一个修改则y_i为0),令z_i=i*y_i,请输出z_1+z_2+...+z_q模10^9+7

    Sample Input

    1
    4 3 7
    1 2 2
    3 0 0
    2 1 3
    3 0 0
    1 0 2
    2 0 0
    4 1 1
    4 0 0

    Sample Output

    32

    HINT

    第1,3,5,7的询问的答案分别为1,3,3,1,所以答案为 1*1+2*0+3*3+4*0+5*3+6*0+7*1=32.
    数据范围:
    对于100%的数据T<=6,n,m,c<=10^5,
    1<=a<=n,0<=l<=n,0<=c<=c

    设dfn[i]为i的dfs序的编号。
    那么每次相当于对所有dfn[x]<=dfn[y]<=son[x]且dep[y]-dep[x]<=L的点进行染色。
    直接KDTree维护矩形染色即可。
     
    代码:
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    #define N 100050
    #define ls ch[p][0]
    #define rs ch[p][1]
    typedef long long ll;
    const int mod=1000000007;
    int head[N],to[N<<1],nxt[N<<1],C[N],n,T;
    int dfn[N],dep[N],mx[N][2],ch[N][2],mn[N][2],root,now,cov[N],son[N],cnt;
    inline void add(int u,int v) {
    	to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt;
    }
    struct Point {
    	int p[2];
    	bool operator < (const Point &x) const {
    		return p[now]==x.p[now]?p[!now]<x.p[!now]:p[now]<x.p[now];
    	}
    }a[N],b[N];
    void pushup(int p,int x) {
    	int i;
    	for(i=0;i<2;i++) mx[p][i]=max(mx[p][i],mx[x][i]),mn[p][i]=min(mn[p][i],mn[x][i]);
    }
    void pushdown(int p) {
    	if(cov[p]!=-1) {
    		cov[ls]=cov[rs]=C[ls]=C[rs]=cov[p];
    		cov[p]=-1;
    	}
    }
    int build(int l,int r,int type) {
    	int mid=(l+r)>>1; now=type;
    	nth_element(a+l,a+mid,a+r+1);
    	int i;
    	for(i=0;i<2;i++) mx[mid][i]=mn[mid][i]=a[mid].p[i];
    	if(l<mid) ch[mid][0]=build(l,mid-1,!type),pushup(mid,ch[mid][0]);
    	if(r>mid) ch[mid][1]=build(mid+1,r,!type),pushup(mid,ch[mid][1]);
    	return mid;
    }
    bool judge(int t1,int t2,int t3,int t4) {
    	return (t1<t3||t1>t4)&&(t2<t3||t2>t4);
    }
    void update(int x,int y,int z,int w,int p,int c) {
    	// printf("%d
    ",p);
    	// printf("%d %d %d %d
    ",x,y,z,w);
    	// a[x].mx[0] < bx || a[x].mn[0] > ex || a[x].mx[1] < by || a[x].mn[1] > ey
    	if(mn[p][0]>=x&&mx[p][0]<=z&&mn[p][1]>=y&&mx[p][1]<=w) {cov[p]=C[p]=c; return ;}
    	if(mx[p][0]<x||mn[p][0]>z||mx[p][1]<y||mn[p][1]>w) return ;
    	pushdown(p);
    	if(a[p].p[0]>=x&&a[p].p[0]<=z&&a[p].p[1]>=y&&a[p].p[1]<=w) C[p]=c;
    	if(ls) update(x,y,z,w,ls,c);
    	if(rs) update(x,y,z,w,rs,c);
    }
    int query(int x) {
    	int p=root;
    	now=0;
    	while(1) {
    		pushdown(p);
    		if(b[x]<a[p]) p=ls;
    		else if(a[p]<b[x]) p=rs;
    		else return C[p];
    		now=!now;
    	}
    }
    void dfs(int x,int y) {
    	int i;
    	dfn[x]=++dfn[0];
    	dep[x]=dep[y]+1;
    	for(i=head[x];i;i=nxt[i]) {
    		if(to[i]!=y) dfs(to[i],x);
    	}
    	son[x]=dfn[0];
    }
    void solve() {
    	int Q;
    	memset(head,0,sizeof(head)); cnt=0;
    	memset(ch,0,sizeof(ch));
    	dfn[0]=0;
    	scanf("%d%*d%d",&n,&Q);
    	int i,x,y;
    	for(i=2;i<=n;i++) {
    		scanf("%d",&x); add(x,i); add(i,x);
    	}
    	dfs(1,0);
    	for(i=1;i<=n;i++) a[i].p[0]=dfn[i],a[i].p[1]=dep[i],cov[i]=-1,C[i]=1,b[i]=a[i];
    	root=build(1,n,0);
    	int ans=0,z;
    	// printf("%d %d %d
    ",dfn[4],son[4],dep[4]);
    	for(i=1;i<=Q;i++) {
    		scanf("%d%d%d",&x,&y,&z);
    		if(z) {
    			update(dfn[x],dep[x],son[x],dep[x]+y,root,z);
    		}else {
    			ans=(ans+ll(i)*query(x)%mod)%mod;
    			// printf("%d
    ",query(x));
    		}
    	}
    	printf("%d
    ",ans);
    }
    int main() {
    	int T;
    	scanf("%d",&T);
    	while(T--) {
    		solve();
    	}
    }
    
  • 相关阅读:
    英文半字节压缩编码技术
    博弈翻硬币游戏
    POJ 2015 Permutation Code
    8051、ARM和DSP指令周期的测试与分析
    Huffman编码
    CentOS 命令提示符颜色及样式详解
    JAVA程序员面试32问
    面向抽象编程:接口和抽象类
    初学实用:实例讲解Java中的接口的作用
    C#和Java的区别
  • 原文地址:https://www.cnblogs.com/suika/p/9279844.html
Copyright © 2011-2022 走看看