zoukankan      html  css  js  c++  java
  • 【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
    ",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;
    }
  • 相关阅读:
    linux内核分析第八周理解进程调度时机跟踪分析进程调度与进程切换的过程
    linux内核分析第六周分析Linux内核创建一个新进程的过程
    Linux内核学习总结
    Linux内核分析第一周通过分析汇编代码理解计算机是如何工作的
    linux内核分析第五周分析system_call中断处理过程
    linux内核分析第三周跟踪分析Linux内核的启动过程
    转载:Understanding WPF Application Lifecycle
    Quick Sort 快速排序
    C#中的Immutable(不变的)
    一个lock和一个deadlock的例子
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/4596779.html
Copyright © 2011-2022 走看看