[bzoj4154][Ipsc2015]Generating Synergy

4154: [Ipsc2015]Generating Synergy

Time Limit: 10 Sec Memory Limit: 512 MB
Submit: 306 Solved: 122
[Submit][Status][Discuss]
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個操作,yi 爲本次詢問的答案(若本次操作是一個修改則yi0 ),令zi=iyi ,請輸出z1+z2+...+zq109+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 ,所以答案爲 11+20+33+40+53+60+71=32.

數據範圍:

對於100%的數據T<=6,n,m,c<=10^5,

1<=a<=n,0<=l<=n,0<=c<=c

因爲只有子節點,所以把樹上的每個點都對應到二維平面中取。
pos[x] 表示xdfs 序,deep[x] 表示x 的深度,每個點的座標就是:(pos[x],deep[x])
染色就是給區間(L[a],R[a],deep[a],deep[a]+l) 賦值。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define LL long long
#define Mod 1000000007
const int N=100010;
struct E{int st,en;}aa[N<<1];
int T,n,m,tot,point[N],next[N<<1],pos[N],dfsn,deep[N],root,D,L[N],R[N];
struct S{
    int c,de,d[2],mi[2],ma[2],l,r;
    int &operator [] (int x){
        return d[x];
    }
    bool operator == (const S &x)const{
        return d[0]==x.d[0]&&d[1]==x.d[1];
    }
    bool operator < (const S &x)const{
        return d[D]==x.d[D]?d[D^1]<x.d[D^1]:d[D]<x.d[D];
    }
}tr[N],p[N],now;
inline int in(){
    int x=0;char ch=getchar();
    while(ch<'0'||ch>'9') ch=getchar();
    while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    return x;
}
inline void add(int x,int y){
    next[++tot]=point[x];point[x]=tot;
    aa[tot].st=x;aa[tot].en=y;
    next[++tot]=point[y];point[y]=tot;
    aa[tot].st=y;aa[tot].en=x;
}
inline void dfs(int x,int last){
    int i;
    L[x]=R[x]=pos[x]=++dfsn;
    for(i=point[x];i;i=next[i])
      if(aa[i].en!=last){
        deep[aa[i].en]=deep[x]+1;
        dfs(aa[i].en,x);
        R[x]=max(R[x],R[aa[i].en]);
      }
}
inline void update(int k){
    int l=tr[k].l,r=tr[k].r,i;
    for(i=0;i<=1;++i){
        tr[k].mi[i]=tr[k].ma[i]=tr[k][i];
        if(l){
            tr[k].mi[i]=min(tr[k].mi[i],tr[l].mi[i]);
            tr[k].ma[i]=max(tr[k].ma[i],tr[l].ma[i]);
        }
        if(r){
            tr[k].mi[i]=min(tr[k].mi[i],tr[r].mi[i]);
            tr[k].ma[i]=max(tr[k].ma[i],tr[r].ma[i]);
        }
    }
}
#define mid (l+r)/2
inline int build(int l,int r,int flag){
    if(l>r) return 0;
    D=flag;nth_element(p+l,p+mid,p+r+1);
    tr[mid]=p[mid];
    tr[mid].l=build(l,mid-1,flag^1);
    tr[mid].r=build(mid+1,r,flag^1);
    update(mid);
    return mid;
}
inline bool in(int k,int x1,int y1,int x2,int y2){
    return tr[k].mi[0]>=x1&&tr[k].ma[0]<=y1&&tr[k].mi[1]>=x2&&tr[k].ma[1]<=y2;
}
inline bool out(int k,int x1,int y1,int x2,int y2){
    return tr[k].mi[0]>y1||tr[k].ma[0]<x1||tr[k].mi[1]>y2||tr[k].ma[1]<x2;
}
inline bool in1(int k,int x1,int y1,int x2,int y2){
    return tr[k][0]>=x1&&tr[k][0]<=y1&&tr[k][1]>=x2&&tr[k][1]<=y2;
}
inline void pushdown(int k){
    int l=tr[k].l,r=tr[k].r,c=tr[k].de;
    if(l) tr[l].de=tr[l].c=c;
    if(r) tr[r].de=tr[r].c=c;
    tr[k].de=0;
}
inline void insert(int k,int x1,int y1,int x2,int y2,int c){
    if(x1>y1||x2>y2||!k) return ;
    if(in(k,x1,y1,x2,y2)){
        tr[k].de=tr[k].c=c;
        return ;
    }
    if(out(k,x1,y1,x2,y2)) return ;
    if(tr[k].de) pushdown(k);
    if(in1(k,x1,y1,x2,y2)) tr[k].c=c;
    int l=tr[k].l,r=tr[k].r;
    if(l&&tr[l].de!=c) insert(tr[k].l,x1,y1,x2,y2,c);
    if(r&&tr[r].de!=c) insert(tr[k].r,x1,y1,x2,y2,c);
}
inline int query(int k,int flag){
    if(now==tr[k]) return tr[k].c;
    if(tr[k].de) pushdown(k);
    if(now[flag]==tr[k][flag]){
        if(now[flag^1]<tr[k][flag^1]) return query(tr[k].l,flag^1);
        else return query(tr[k].r,flag^1);
    }
    else if(now[flag]<tr[k][flag]) return query(tr[k].l,flag^1);
    else return query(tr[k].r,flag^1);
}
int main(){
    T=in();
    while(T--){
        tot=dfsn=0;
        memset(point,0,sizeof(point));
        int i,x,j,y,z,ans=0;
        n=in();m=in();m=in();
        for(i=2;i<=n;++i){
            x=in();
            add(x,i);
        }
        dfs(1,0);
        for(i=1;i<=n;++i){
            p[i].c=1;
            p[i].de=0;
            p[i][0]=pos[i];
            p[i][1]=deep[i];
            for(j=0;j<=1;++j)
              p[i].mi[j]=p[i].ma[j]=p[i][j];
        }
        root=build(1,n,0);
        for(i=1;i<=m;++i){
            x=in();y=in();z=in();
            if(z) insert(root,L[x],R[x],deep[x],deep[x]+y,z);
            else{
                now[0]=pos[x];
                now[1]=deep[x];
                int c=query(root,0);
                ans=(ans+(int)(((LL)c*(LL)i)%Mod))%Mod;
            }
        }
        printf("%d\n",ans);
    }
}
發佈了155 篇原創文章 · 獲贊 191 · 訪問量 14萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章