CSU oj 1322: ZZY‘s new company

地址:http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1322

1322: ZZY‘s new company

Time Limit: 3 Sec   Memory Limit: 312 MB
Submit: 153   Solved: 18
[ Submit][ Status][ Web Board]

Description

  zzy开了一家公司,然后他为公司制定了人事制度:为每个员工都定一个直接的上属(除了zzy自己),这样就把公司表示成了一个树形的人事关系图,树的最顶端就是zzy自己。如果a的直接上属是b则称a是b的一级下属,接下去的依次称为2级、3级……k级下属。

  由于如zzy奇葩的想法,他将改变一部分员工的工资,方法依旧是将员工原来的工资异或一个数,得到新的工资。

Input

  每个例子的第一行含两个数N和Q,表示zzy找了N(0

  接下来的N行,每行有两个数Ui和Vi(第i行表示id为i的员工资料),表示员工i的上属编号为Ui,原始工资为Vi。然后有Q行,每行的第一个数是a,为0或者1表示一种询问。

  如果a为0,则这行还有三个数b,c,v(0<=b<=N, 0 < c, v<=1000000000),表示zzy将b的所有c级下属工资全部异或v,得到新工资。

  如果a为1,则这行还有两个数b,c(0<=b<=N, 0 < c),询问b的所有c级下属的总工资。

Output

  对于每个修改,如果b没有c级的下属则无视这个修改。

  对于每个询问,输出一个数来表示结果,如果b没有c级下属则输出-1。

Sample Input

3 3
0 1
1 2
2 4
1 0 1
0 0 1 3
1 0 1
3 4
0 1
0 2
0 3
1 0 1
0 0 1 6
1 0 1
1 0 2

Sample Output

1
2
6
16
-1 


因为更新是异或操作,所以需要按二进制来建线段树,建了30棵线段树,分别表示在这个区间在这一位二进制上有多少个1.

然后就是更新距离为c的点,我们将点按深度升序和dfs序排序,那么深度相同的点就在一块了,在记录每个点dfs序产生的儿子区间,每次操作就是取这俩个区间的交集。


#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
 
typedef long long ll;
#define rep(i,s,t) for(int i=s;i=t;i--)
#define ree(i,now) for(int i=head[now];i!=-1;i=edge[i].next)
#define clr(a,v) memset(a,v,sizeof a)
#define L t<<1
#define R t<<1|1
#define MID(l,r) int mid=(l+r)>>1
#define lowbit(x) (x&(-x))
#define SQR(a) ((a)*(a))
 
inline int input(){
    int ret=0;bool isN=0;char c=getchar();
    while(c<'0' || c>'9'){
        if(c=='-') isN=1;
        c=getchar();
    }
    while(c>='0' && c<='9'){
        ret=ret*10+c-'0';
        c=getchar();
    }
    return isN?-ret:ret;
}
 
inline void output(int x){    
    if(x<0){    
        putchar('-');x=-x;    
    }    
    int len=0,data[11];    
    while(x){    
        data[len++]=x%10;x/=10;    
    }    
    if(!len)    data[len++]=0;    
    while(len--)   
        putchar(data[len]+48);    
    putchar('\n');  
}  
 
const int MAXN=100005;
struct Node{
    int id,dep,to;
    bool operator < (const Node &a) const{
        return dep=x && r<=y){
        changeVal(t,pos);
        return;
    }
    push_down(t,pos);
    MID(l,r);
    if(y<=mid) modefiy(pos,L,l,mid,x,y);
    else if(x>mid)   modefiy(pos,R,mid+1,r,x,y);
    else{
        modefiy(pos,L,l,mid,x,mid);
        modefiy(pos,R,mid+1,r,mid+1,y);
    }
    push_up(t,pos);
}
 
inline int query(int pos,int t,int l,int r,int x,int y){
    if(l>=x && r<=y) return sum[pos][t];
    push_down(t,pos);MID(l,r);
    if(y<=mid) return query(pos,L,l,mid,x,y);
    else if(x>mid) return query(pos,R,mid+1,r,x,y);
    else return query(pos,L,l,mid,x,mid)+query(pos,R,mid+1,r,mid+1,y);
}
 
int start[MAXN];
int end[MAXN];
int op,x,y,z;
 
inline int Binary_Search(int s,int t,int v,bool e){
    if(man[s].to>=v) return s;
    if(man[t].to<=v) return t;
    while(s<=t){
        MID(s,t);
        if(man[mid].to<=v) s=mid+1;
        else t=mid-1;
    }
    if(e && man[s].to>v) s--; 
    return s;
}
 
int main(){
    while(~scanf("%d%d",&n,&m)){
        clr(head,-1),e=tot=0;
        rep(i,0,n+1) man[i].id=i; 
        wage[0]=0;
        rep(i,1,n+1){
            boss[i]=input();wage[i]=input();
            addEdge(boss[i],i);
        }
        man[0].dep=0;
        dfs(0,0);dfs1(0,0);
        sort(man,man+n+1);
        /*rep(i,0,n+1){
            cout<maxDep[x]) continue;
                int s=start[y],e=end[y];
                int a=Binary_Search(s,e,to[x],0)+1;
                int b=Binary_Search(s,e,last[x],1)+1;
                rep(i,0,30){
                    if(z&(1<maxDep[x]) puts("-1");
                else{
                    ll ans=0;
                    int s=start[y],e=end[y];
                    int a=Binary_Search(s,e,to[x],0)+1;
                    int b=Binary_Search(s,e,last[x],1)+1;
                    rep(i,0,30){
                        ans+=(1<


你可能感兴趣的:(ACM)