zoukankan      html  css  js  c++  java
  • 【BZOJ4154】[Ipsc2015]Generating Synergy KDtree

    【BZOJ4154】[Ipsc2015]Generating Synergy

    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

    题解:想了半天奇怪的做法,正解居然是KDtree?

    KDtree的第一维是DFS序,第二维是深度,区间修改用打标记实现,查询时下传标记,剩下的就不用说了吧?

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    const ll P=1000000007;
    const int maxn=100010;
    int n,m,D,rt,cnt;
    ll ans;
    int to[maxn],next[maxn],head[maxn],p[maxn],q[maxn],fa[maxn],L[2],R[2],dep[maxn],st[maxn],pos[maxn];
    struct kd
    {
    	int ls,rs,fa,tag,col,org,v[2],sm[2],sn[2];
    	kd(){}
    	kd(int a,int b,int c){sm[0]=sn[0]=v[0]=a,sm[1]=sn[1]=v[1]=b,org=c,ls=rs=fa=0,tag=0,col=1;}
    }t[maxn];
    bool cmp(const kd &a,const kd &b)
    {
    	return	(a.v[D]==b.v[D])?(a.v[D^1]<b.v[D^1]):(a.v[D]<b.v[D]);
    }
    inline int rd()
    {
    	int ret=0,f=1;	char gc=getchar();
    	while(gc<'0'||gc>'9')	{if(gc=='-')f=-f;	gc=getchar();}
    	while(gc>='0'&&gc<='9')	ret=ret*10+gc-'0',gc=getchar();
    	return ret*f;
    }
    inline void add(int a,int b)
    {
    	to[cnt]=b,next[cnt]=head[a],head[a]=cnt++;
    }
    void dfs(int x)
    {
    	p[x]=++p[0];
    	for(int i=head[x];i!=-1;i=next[i])	dep[to[i]]=dep[x]+1,dfs(to[i]);
    	q[x]=p[0];
    }
    inline void pushup(int x,int y)
    {
    	t[x].sm[0]=max(t[x].sm[0],t[y].sm[0]);
    	t[x].sn[0]=min(t[x].sn[0],t[y].sn[0]);
    	t[x].sm[1]=max(t[x].sm[1],t[y].sm[1]);
    	t[x].sn[1]=min(t[x].sn[1],t[y].sn[1]);
    }
    inline void pushdown(int x)
    {
    	if(t[x].tag)
    	{
    		if(t[x].ls)	t[t[x].ls].col=t[t[x].ls].tag=t[x].tag;
    		if(t[x].rs)	t[t[x].rs].col=t[t[x].rs].tag=t[x].tag;
    		t[x].tag=0;
    	}
    }
    int build(int l,int r,int d)
    {
    	if(l>r)	return 0;
    	int mid=(l+r)>>1;
    	D=d,nth_element(t+l,t+mid,t+r+1,cmp),pos[t[mid].org]=mid;
    	t[mid].ls=build(l,mid-1,d^1),t[mid].rs=build(mid+1,r,d^1);
    	if(t[mid].ls)	t[t[mid].ls].fa=mid,pushup(mid,t[mid].ls);
    	if(t[mid].rs)	t[t[mid].rs].fa=mid,pushup(mid,t[mid].rs);
    	return mid;
    }
    void updata(int x,int y)
    {
    	if(!x||t[x].sn[0]>R[0]||t[x].sm[0]<L[0]||t[x].sn[1]>R[1]||t[x].sm[1]<L[1])	return ;
    	pushdown(x);
    	if(t[x].sm[0]<=R[0]&&t[x].sn[0]>=L[0]&&t[x].sm[1]<=R[1]&&t[x].sn[1]>=L[1])
    	{
    		t[x].tag=t[x].col=y;
    		return ;
    	}
    	if(t[x].v[0]<=R[0]&&t[x].v[0]>=L[0]&&t[x].v[1]<=R[1]&&t[x].v[1]>=L[1])	t[x].col=y;
    	updata(t[x].ls,y),updata(t[x].rs,y);
    }
    inline int query(int x)
    {
    	st[st[0]=1]=x;
    	while(t[st[st[0]]].fa)	st[st[0]+1]=t[st[st[0]]].fa,st[0]++;
    	while(st[0])	pushdown(st[st[0]]),st[0]--;
    	return t[x].col;
    }
    void work()
    {
    	n=rd(),rd(),m=rd();
    	memset(head,-1,sizeof(head)),cnt=0,ans=0;
    	int i,a,b,c;
    	for(i=2;i<=n;i++)	fa[i]=rd(),add(fa[i],i);
    	dep[1]=1,dfs(1);
    	for(i=1;i<=n;i++)	t[i]=kd(p[i],dep[i],i);
    	rt=build(1,n,0);
    	for(i=1;i<=m;i++)
    	{
    		a=rd(),b=rd(),c=rd();
    		if(!c)	ans=(ans+(ll)i*query(pos[a]))%P;
    		else	L[0]=p[a],R[0]=q[a],L[1]=dep[a],R[1]=dep[a]+b,updata(rt,c);
    	}
    	printf("%lld
    ",ans);
    }
    int main()
    {
    	int T=rd();
    	while(T--)	work();
    	return 0;
    }//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
  • 相关阅读:
    正则表达式 \n和\r
    【转】单循环赛赛程安排算法研究
    Iterator效率
    Map获取键值
    PL/SQL语法详解(pdf)
    Iterator模式
    测试js函数的静态页面
    【转】java的一些基本概念
    Oracle 11g用户解锁
    oracle官方文档
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/7535746.html
Copyright © 2011-2022 走看看