zoukankan      html  css  js  c++  java
  • bzoj4154: [Ipsc2015]Generating Synergy

    //Achen
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<vector>
    #include<queue>
    #include<ctime>
    #include<cmath>
    const int N=1e5+7;
    const int mod=1e9+7;
    typedef long long LL;
    using namespace std;
    int rt,n,y,D,T,c,q,data[N][2][2],ch[N][2],col[N],lz[N];
    LL ans;
    
    template<typename T> void read(T &x) {
        char ch=getchar(); x=0; T f=1;
        while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
        if(ch=='-') f=-1,ch=getchar();
        for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
    }
    
    struct node{
        int d[2];
        friend bool operator <(const node &A,const node&B) {
            return A.d[D]<B.d[D];
        } 
    }a[N],tp;
    
    int ecnt,fir[N],nxt[N],to[N],fa[N];
    void add(int u,int v) {
        nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v;
    }
    
    int dfs_clock,dfn[N],low[N],R[N];
    void dfs(int x) {
        dfn[x]=low[x]=++dfs_clock;
        R[x]=R[fa[x]]+1;
        a[x].d[0]=dfn[x]; a[x].d[1]=R[x];
        for(int i=fir[x];i;i=nxt[i]) {
            dfs(to[i]);
            low[x]=max(low[x],low[to[i]]);
        }
    }
    
    void update(int x) {
        for(int i=0;i<2;i++)
            for(int j=0;j<2;j++)
                data[x][i][j]=a[x].d[i];
        for(int i=0;i<2;i++)
            if(y=ch[x][i])
            for(int j=0;j<2;j++)
                data[x][j][0]=min(data[x][j][0],data[y][j][0]),
                data[x][j][1]=max(data[x][j][1],data[y][j][1]);
    }
    
    #define lc ch[x][0]
    #define rc ch[x][1]
    int build(int l,int r,int k) {
        if(l>r) return 0; 
        D=k;
        int mid=((l+r)>>1);
        nth_element(a+l,a+mid,a+r+1);
        ch[mid][0]=build(l,mid-1,k^1);
        ch[mid][1]=build(mid+1,r,k^1);
        update(mid);
        return mid;
    } 
    
    void down(int x) {
        if(!lz[x]) return;
        if(lc) col[lc]=col[x],lz[lc]=1;
        if(rc) col[rc]=col[x],lz[rc]=1;
        lz[x]=0;
    }
    
    int in(int x) {
        return data[x][0][0]<=tp.d[0]&&data[x][0][1]>=tp.d[0]
        &&data[x][1][0]<=tp.d[1]&&data[x][1][1]>=tp.d[1];
    }
    
    int ok(int x,int l1,int r1,int l2,int r2) {
        int f=1;
        if(!((data[x][0][0]>=l1&&data[x][0][0]<=r1)
        ||(data[x][0][1]>=l1&&data[x][0][1]<=r1)||
        (data[x][0][0]<=l1&&data[x][0][1]>=r1))) f=0;
        if(!((data[x][1][0]>=l2&&data[x][1][0]<=r2)
        ||(data[x][1][1]>=l2&&data[x][1][1]<=r2)||
        (data[x][1][0]<=l2&&data[x][1][1]>=r2))) f=0;
        return f;
    }
    
    int find(int x) {
        if(a[x].d[0]==tp.d[0]&&a[x].d[1]==tp.d[1]) return col[x];
        down(x); int res=0;
        if(in(lc)) res=find(lc);
        if(!res&&in(rc)) res=find(rc);
        return res;                        
    }
    
    void change(int x,int l1,int r1,int l2,int r2,int v) {
        if(data[x][0][0]>=l1&&data[x][0][1]<=r1&&
        data[x][1][0]>=l2&&data[x][1][1]<=r2) {
            col[x]=v,lz[x]=1; return;
        }
        down(x);
        if(a[x].d[0]>=l1&&a[x].d[0]<=r1&&
        a[x].d[1]>=l2&&a[x].d[1]<=r2) col[x]=v;
        if(ok(lc,l1,r1,l2,r2)) change(lc,l1,r1,l2,r2,v);
        if(ok(rc,l1,r1,l2,r2)) change(rc,l1,r1,l2,r2,v);
    }
    
    void work() {
        dfs(1);
        for(int i=1;i<=n;i++) col[i]=1,lz[i]=0;
        rt=build(1,n,0);
        for(int i=1;i<=q;i++) {
            int x,h,c;
            read(x); read(h); read(c);
            if(!c) {
                tp.d[0]=dfn[x]; tp.d[1]=R[x];
                (ans+=(LL)i*(find(rt)))%=mod;
            }
            else change(rt,dfn[x],low[x],R[x],R[x]+h,c);
        }
        printf("%lld
    ",ans);
    }
    
    void init() {
        read(T);
        while(T--) {
            read(n); 
            read(c); 
            read(q); 
            for(int i=2;i<=n;i++) {
                read(fa[i]);
                add(fa[i],i);
            }
            work(); 
            ans=0; ecnt=0; 
            memset(fir,0,sizeof(fir));
            memset(data,0,sizeof(data));
            memset(ch,0,sizeof(ch));
        }
    }
    
    int main() {
        init();
        return 0;
    }
    View Code
  • 相关阅读:
    Vasya and Endless Credits CodeForces
    Dreamoon and Strings CodeForces
    Online Meeting CodeForces
    数塔取数 基础dp
    1001 数组中和等于K的数对 1090 3个数和为0
    1091 线段的重叠
    51nod 最小周长
    走格子 51nod
    1289 大鱼吃小鱼
    POJ 1979 Red and Black
  • 原文地址:https://www.cnblogs.com/Achenchen/p/8021433.html
Copyright © 2011-2022 走看看