【kd-tree】bzoj4154 [Ipsc2015]Generating Synergy

区间修改的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[N],val,delta[N];
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[N];
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[N],next[N],first[N],e;
void AddEdge(const int &U,const int &V)
{
    v[++e]=V;
    next[e]=first[U];
    first[U]=e;
}
int dep[N],dfn[N],dfr[N];
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[N];
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;
}
posted @ 2015-06-24 09:06  AutSky_JadeK  阅读(232)  评论(0编辑  收藏  举报
TVアニメ「Charlotte(シャーロット)」公式サイト TVアニメ「Charlotte(シャーロット)」公式サイト