hdu5416

来源:互联网 发布:js new操作符 编辑:程序博客网 时间:2024/04/29 18:40

通过这道题来看,异或或许和最近公共祖先之间有着某种关系。最近公共祖先,是(1,n),(1,v)去掉相同的部分,而异或也是异或两次相当于没有异或。剩下的就好说了,纯暴力。本来以为会超时,但是竟然过了,以前以为不会超时的题,竟然超时了,所以说学好时间复杂度很重要。至于N的选值要注意。还有最后ans的处理上,也要注意,有些点对会出现两次,但是有的只出现一次。所以要进行处理后在除以2。一直wr在了ans的处理上,看了别人的代码受到启发。

代码参考:http://blog.csdn.net/DoJintian/article/details/47834933

2015.8.29:

hahaha到此一游

#include<stdio.h>#include<string.h>#include<iostream>using namespace std;#define N 262200int dp[N];long long int numcou[N];int head[N],to[2*N],nextedge[2*N],w[2*N];int cou;void add(int a,int b,int c){    to[cou]=b;w[cou]=c;nextedge[cou]=head[a];head[a]=cou++;//printf("wo shi da hao ren");    //printf("%d %d %d %d\n",a,b,c,cou);}void dfs(int u,int fa){    numcou[dp[u]]++;    //printf("%d %dha\n",u,head[u]);    for(int i=head[u];i!=-1;i=nextedge[i]){        int v=to[i];        if(v==fa){            continue;        }        else{            dp[v]=w[i]^dp[u];            //printf("%d %d %d\n",u,v,w[i]);            dfs(v,u);        }    }    return;}int main(){    int t;    int n;    int q;    int a,b,c;    scanf("%d",&t);    while(t--){        scanf("%d",&n);        cou=0;        memset(head,-1,sizeof(head));        for(int i=1;i<n;i++){            scanf("%d%d%d",&a,&b,&c);            add(a,b,c);            add(b,a,c);        }        memset(numcou,0,sizeof(numcou));        dp[1]=0;        dfs(1,-1);        /*for(int i=1;i<=n;i++){            printf("%d ",dp[i]);        }*/        scanf("%d",&q);        for(int i=0;i<q;i++){            scanf("%d",&a);            long long int ans=0;            for(int i=0;i<N;i++){                int temp=a^i;                ans=ans+numcou[temp]*numcou[i];            }            if(!a){                ans=ans+n;            }            printf("%lld\n",ans/2);        }    }    return 0;}


0 0
原创粉丝点击