• LOJ #2013「SCOI2016」幸运数字


    时限为什么这么大啊

    明摆着放多$ log$的做法过啊$QAQ$

    LOJ #2013


    题意

    有$ Q$次询问,每次询问树上一条链,点有点权,你需要选择一些链上的点使得异或和尽量大

    点数$ leq 2*10^4$ 询问数$ leq 2*10^5$ 值域不超过$ 2^{64}$


    $ Solution$

    直接点分

    把询问用$ vector$挂在当前点分中心上

    计算一个点的时候 

    递归计算它统率的子树,在每个点挂上从自己到根的线性基,

    每次相当于继承父亲的线性基并插入一个数

    然后将询问分成两类

    不过当前点分中心的:下放到之后的点分计算

    经过当前点分中心的:每次进行一次线性基合并然后求线性基最大值

    总复杂度$ O(Q·60^2+n·60·log n)$


    $My code$

    #include<ctime>
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    #define ull unsigned long long 
    #define M 40010
    #define file(x)freopen(x".in","r",stdin);freopen(x".out","w",stdout)
    #define rt register int
    #define l putchar('
    ')
    #define ll long long
    #define r read()
    using namespace std;
    inline ll read(){
        ll x = 0; char zf = 1; char ch = getchar();
        while (ch != '-' && !isdigit(ch)) ch = getchar();
        if (ch == '-') zf = -1, ch = getchar();
        while (isdigit(ch)) x = x * 10 + ch - '0', ch = getchar(); return x * zf;
    }
    void write(ull y){if(y<0)putchar('-'),y=-y;if(y>9)write(y/10);putchar(y%10+48);}
    void writeln(const ull y){write(y);putchar('
    ');}
    int k,m,n,x,y,z,cnt;ull ans[200010];
    struct xxj{//线性基 
        #define sz 60
        ull a[sz+1];
        xxj(){memset(a,0,sizeof(a));}
        void insert(ull x){
            for(rt i=sz;x;i--)if(x>>i&1){
                if(!a[i])return a[i]=x,void();
                x^=a[i];
            }
        }
        bool check(const ull x){
            for(rt i=sz;i>=0;i--)if(x>>i&1)if(!a[i])return 1;
            return 0;
        }
        void rebuild(){
            for(rt i=sz;i>=0;i--)if(a[i])
            for(rt j=i-1;j>=0;j--)if(a[j]>>i&1)a[j]^=a[i];
        }
        ull Max(){
            ull ret=0;
            for(rt i=sz;i>=0;i--)if((ret^a[i])>ret)ret^=a[i];
            return ret;
        }
        ull Min(){
            for(rt i=0;i<=sz;i++)if(a[i])return a[i];
            return 0;
        }
        ull kth(ull rk){
            rebuild();ull ret=0;
            for(rt i=0,j=0;i<=sz;i++){
                while(j<=sz&&!a[j])j++;
                if(rk>>i&1){
                    if(j>sz)return 0;
                    ret^=a[j];
                }j++;
            }
            return ret;
        }
    };
    xxj merge(const xxj x,const xxj y){
        xxj ret=y;
        for(rt i=sz;i>=0;i--)if(x.a[i])ret.insert(x.a[i]);
        return ret;
    }
    #undef sz
    struct query{
        int x,y,id;
    };
    vector<query>ask[40010];
    int nowmin,all,size[20010],Root,troot;
    int F[M],L[M],N[M],a[M];ull v[M];bool vis[M];
    void add(int x,int y){
        a[++k]=y;
        if(!F[x])F[x]=k;
        else N[L[x]]=k;
        L[x]=k;
    }
    void getroot(int x,int pre){
        size[x]=1;int maxsize=0;
        for(rt i=F[x];i;i=N[i])if(!vis[a[i]]&&a[i]!=pre){
            getroot(a[i],x);
            size[x]+=size[a[i]];
            maxsize=max(maxsize,size[a[i]]);
        }
        maxsize=max(maxsize,all-size[x]);
        if(maxsize<nowmin)nowmin=maxsize,Root=x;
    }
    int color[M];
    void dfs_color(int x,int pre,int col){
        color[x]=col;
        for(rt i=F[x];i;i=N[i])if(a[i]!=pre&&!vis[a[i]])dfs_color(a[i],x,col);
    }
    xxj c[20010];
    void dfs_calc(int x,int pre){
        if(x==pre)memset(c[x].a,0,sizeof(c[x].a));else c[x]=c[pre];
        c[x].insert(v[x]);
        for(rt i=F[x];i;i=N[i])if(a[i]!=pre&&!vis[a[i]])dfs_calc(a[i],x); 
    }
    void calc(int x){
        vis[x]=1;color[x]=233333+x;
        for(rt i=F[x];i;i=N[i])if(!vis[a[i]])dfs_color(a[i],x,a[i]);    
        dfs_calc(x,x);
        for(auto i:ask[x]){
            if(color[i.x]!=color[i.y])
            ans[i.id]=max(ans[i.id],merge(c[i.x],c[i.y]).Max());
        }
        const int ls=all;
        for(auto i:ask[x])if(color[i.x]==color[i.y])ask[color[i.x]+20000].push_back(i);
        for(rt i=F[x];i;i=N[i])if(!vis[a[i]]){
            if(size[a[i]]>size[x])all=nowmin=ls-size[x];else all=nowmin=size[a[i]];
            getroot(a[i],x);ask[Root].clear();
            ask[Root]=ask[a[i]+20000];ask[a[i]+20000].clear();
            calc(Root);
        }
    }
    int main(){
        n=r;m=r;
        for(rt i=1;i<=n;i++)v[i]=r;
        for(rt i=1;i<n;i++){
            x=r;y=r;
            add(x,y);
            add(y,x);
        }
        nowmin=all=n;getroot(1,1);troot=Root;
        for(rt i=1;i<=m;i++){
            x=r;y=r;
            if(x==y)ans[i]=v[x];else
            ask[troot].push_back({x,y,i});
        }
        calc(troot);
        for(rt i=1;i<=m;i++)writeln(ans[i]);
        return 0;
    }
  • 相关阅读:
    [Oracle] CPU/PSU补丁安装详细教程
    weblogic 升级bsu_Weblogic补丁升级之坑坑洼洼
    weblogic补丁下载与安装补丁的方法
    weblogic补丁安装失败
    【项目】项目56
    【项目】项目55
    【项目】项目54
    【项目】项目53
    【项目】项目52
    【项目】项目51
  • 原文地址:https://www.cnblogs.com/DreamlessDreams/p/10110444.html
Copyright © 2020-2023  润新知