zoukankan      html  css  js  c++  java
  • Xor路

    Xor路

    (xor.pas/c/cpp)128MB1s

    给定一棵有N个点和N-1条边的树,请你求出树中的最长路径,以及总共有多少条最长路径。

    这里路径长度是用xor定义的,即若经过的边的权值为a1, a2, a3,...,an,则这条路径的总权值为 a1 xor a2 xor a3 ... xor an。

    输入格式

    1行为一个正整数 N,为点的个数。

    2行至第N行,每行包含三个正整数x,y,z,表示x和y之间有一条权值为z的边。

    输出格式

    仅一行,包含两个数字,为最长路径的长度和条数。

    样例输入

    4

    1 2 3

    2 4 1

    1 3 4

    样例输出

    7 1

    样例解释

    2-1-3 这条路径,长度为3 xor 4=7。

    ————————————————————————————————————————————————

    首先xor满足 a&a=0

    这样之后我们求两个点之间的路径就可以随便找一个点作为树的跟两个点之间的路径就是两个点到跟的路径的xor

    这样问题就转换成了给你n个数求两个点亦或和最大值以及方案数

    这个n^2明显会超时 但是利用xor的性质 我们可以利用tire来维护 复杂度nlogn

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define LL long long
    using namespace std;
    const int M=3e5+7;
    int n,x,y,vis[M],q[M];
    LL l[3500007][2],h[3500007];
    LL T,w,d[M],mx,ans,sum;
    int first[M],cnt;
    struct node{int to,next; LL w;}e[2*M];
    void ins(int a,int b,LL w){cnt++; e[cnt].to=b; e[cnt].w=w; e[cnt].next=first[a]; first[a]=cnt;}
    void insert(int a,int b,LL w){ins(a,b,w); ins(b,a,w);}
    void spfa(){
        int head=0,tail=1;
        q[0]=1; vis[1]=1;
        while(head!=tail){
            int x=q[head++]; if(head>M) head=0;
            for(int i=first[x];i;i=e[i].next){
                int now=e[i].to;
                if(vis[now]) continue;
                vis[now]=1; q[tail++]=now; d[now]=d[x]^e[i].w;
                if(tail>M) tail=0;
            }
        }
    }
    void insert(int num){
        int x=0,now;
        for(int i=30;i>=0;i--){
            now=(num&(1<<i))>>i;
            if(!l[x][now]) l[x][now]=++sum;
            x=l[x][now];
        }
        h[x]++;
    }
    int find(int num){
        int x=0,now;
        for(int i=30;i>=0;i--){
            now=(num&(1<<i))>>i;
            if(l[x][!now]) x=l[x][!now],T+=(1<<i);
            else x=l[x][now];
        }
        return h[x];
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<n;i++) scanf("%d %d %lld",&x,&y,&w),insert(x,y,w);
        spfa();
        for(int i=1;i<=n;i++) insert(d[i]);
        for(int i=1;i<=n;i++){
            T=0; int p=find(d[i]);
            if(T>mx) mx=T,ans=p;
            else if(T==mx) ans+=p;
        }
        printf("%lld %lld
    ",mx,ans>>1);
        return 0;
    }
    View Code

     

  • 相关阅读:
    JMETER-02-常用方法-全局变量,逻辑控制器,随机控制器,吞吐量控制器,加断言,事物控制器 ,循环控制器,仅一次控制器,foreach控制器
    接口自动化01接口基础-之接口的调用之postman和jmeter
    接口自动化01接口基础
    php中的9大缓存技术总结
    tp5自动生成目录
    PHP 服务器变量 $_SERVER
    从正则表达式的iUs说说模式修正符
    简单介绍下MYSQL的索引类型
    mysql几种存储引擎介绍
    PHP中return 和 exit 、break和contiue 区别与用法
  • 原文地址:https://www.cnblogs.com/lyzuikeai/p/7327373.html
Copyright © 2011-2022 走看看