zoukankan      html  css  js  c++  java
  • hdu5589Tree

    题解:我们考虑维护每个点到根路径的异或和 这样的话两个数异或就等于这条路径的异或和 这样的话我们可以用莫队转移 然后用字典树贪心统计答案

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <cmath>
    #include <set>
    #include <map>
    #define mp make_pair
    #define pb push_back
    #define pii pair<int,int>
    #define link(x) for(edge *j=h[x];j;j=j->next)
    #define inc(i,l,r) for(int i=l;i<=r;i++)
    #define dec(i,r,l) for(int i=r;i>=l;i--)
    const int MAXN=5e4+10;
    const double eps=1e-8;
    #define ll long long
    using namespace std;
    struct edge{int t,v;edge*next;}e[MAXN<<1],*h[MAXN],*o=e;
    void add(int x,int y,int vul){o->t=y;o->v=vul;o->next=h[x];h[x]=o++;}
    ll read(){
        ll x=0,f=1;char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
        return x*f;
    }
    int n,m,q;
    int a[MAXN],pos[21];ll ans2[MAXN];
    void dfs(int x,int pre){
    	link(x){
    		if(j->t!=pre){a[j->t]=(a[x]^(j->v));dfs(j->t,x);}
    	}
    }
    int p[MAXN],sz,cnt,rt;
    typedef struct node{
    	int ch[2],num;
    }node;
    node d[MAXN*21];
    void newnode(int &x){
    	x=++cnt;d[x].ch[0]=d[x].ch[1]=d[x].num=0;
    }
    void insert(int x){
    	int temp=rt;
    	for(int i=20;i>=0;i--){
    		 int t=((x>>i)&1);
    		 if(!d[temp].ch[t])newnode(d[temp].ch[t]);
    		 temp=d[temp].ch[t];
    		 d[temp].num++;
    	}
    }
    void Delete(int x){
    	int temp=rt;
    	for(int i=20;i>=0;i--){
    		int t=((x>>i)&1);
    		temp=d[temp].ch[t];
    		d[temp].num--;
    	}
    }
    int Calc(int x){
    	int temp=rt;int ans=0;
    	for(int i=20;i>=0;i--){
    		int t=((x>>i)&1);
    		if(pos[i]){
    			if(t)temp=d[temp].ch[0];
    			else temp=d[temp].ch[1];
    		}
    		else{
    			if(t)ans+=d[d[temp].ch[0]].num,temp=d[temp].ch[1];
    			else ans+=d[d[temp].ch[1]].num,temp=d[temp].ch[0];
    		}
    	}
    	return ans;
    }
    typedef struct Q{
    	int l,r,id;
    	friend bool operator<(Q aa,Q bb){
    		if(p[aa.l]==p[bb.l])return aa.r<bb.r;
    		else return p[aa.l]<p[bb.l];
    	}
    }Q;
    Q que[MAXN];
    int main(){
    	while(scanf("%d%d%d",&n,&m,&q)!=EOF){
    		memset(h,0,sizeof(h));memset(e,0,sizeof(e));o=e;
    		dec(i,20,0)pos[i]=((m>>i)&1);
    		cnt=0;newnode(rt);
    		sz=(int)sqrt(n);
    		inc(i,1,n)p[i]=(i-1)/sz+1;
    		int u,v,vul;
    		inc(i,1,n-1)u=read(),v=read(),vul=read(),add(u,v,vul),add(v,u,vul);
    		dfs(1,0);
    		inc(i,1,q)que[i].l=read(),que[i].r=read(),que[i].id=i;
    		sort(que+1,que+q+1);
    		int L=1;int R=0;ll ans1=0;
    		for(int i=1;i<=q;i++){
    			while(R>que[i].r){
    				ans1-=Calc(a[R]);Delete(a[R]);
    				R--;
    			}
    			while(R<que[i].r){
    				R++;
    				ans1+=Calc(a[R]);insert(a[R]);
    			}
    			while(L<que[i].l){
    				ans1-=Calc(a[L]);Delete(a[L]);
    				L++;
    			}
    			while(L>que[i].l){
    				L--;
    				ans1+=Calc(a[L]);insert(a[L]);
    			}
    			ans2[que[i].id]=ans1;
    		}
    		inc(i,1,q)printf("%lld
    ",ans2[i]);
    	}
    	return 0;
    }
    

    Tree

    Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
    Total Submission(s): 511    Accepted Submission(s): 210


    Problem Description
    There is a tree, whose vertices are labeled by 1, 2, …, N. They are connected by N–1 edges. Each edge has a weight.For any two vertices u and v, f(u,v) is xor(exclusive-or) sum of weights of all edges on the path from u to v.There are Q queries,for each query,giving you a interval [l,r], you should calculate the number of pairs (u,v) such that f(u,v) > M (lu<vr) 。
     
    Input
    There are multiple test cases.
    For each case contains 3 integers N, M and Q on a line.(1N,M,Q50000)
    Each of the next N - 1 lines contains three space separated integers a, b and c denoting an edge between a and b, whose weight is c.(1a,bN,0c50000)
    Each of the next Q lines contains two integers l and r.(1lrN)
     
    Output
    For each query,output the answer in a line.
     
    Sample Input
    5 10 3 1 2 13 2 3 15 2 4 17 2 5 8 1 5 2 4 3 3
     
    Sample Output
    6 3 0
     
  • 相关阅读:
    语言相关
    一道简单DP题
    一道概率题
    Android CrashHandler
    一道简单数学题
    面试中遇到的随机题目
    VMWare 无损扩展磁盘大小
    Android 源码编译记录
    Android handler 内存泄露分析及解决方法
    Android 反编译
  • 原文地址:https://www.cnblogs.com/wang9897/p/9948867.html
Copyright © 2011-2022 走看看