zoukankan      html  css  js  c++  java
  • 2017沈阳网络赛G XOR 分块(分类讨论sqrt)

    题意:一棵树,点权,Q次询问,A---B路径上每K个点的异或和

    链接:点击打开链接

    思路:分类讨论,k小于200,类似dp的预处理,在求lca的过程中可以求出来,k大于200,直接暴力跳,最多跳sqrtn步,其中还带个log的倍增。1200ms AC。。

    PS  :场上手残。。。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int MAXN = 100010;
    const int DEG = 20;
    int root;
    struct Edge{
        int to,next;
    } edge[MAXN*2];
    int head[MAXN],tot;
    void addedge(int u,int v){
        edge[tot].to = v;
        edge[tot].next = head[u];
        head[u] = tot++;
    }
    void init(){
        tot = 0;
        memset(head,-1,sizeof(head));
    }
    int fa[MAXN][DEG];//fa[i][j]表示结点i的第2^j个祖先
    int deg[MAXN];//深度数组
    int w[MAXN];
    int dp[MAXN][205];
    int fa2[MAXN][205];
    void BFS(int root){
        queue<int>que;
        deg[root] = 0;
        fa[root][0] = root;
        que.push(root);
        while(!que.empty()){
            int tmp = que.front();
            que.pop();
            for(int i = 1; i < DEG; i++)
                fa[tmp][i] = fa[fa[tmp][i-1]][i-1];
            fa2[tmp][0]=tmp;
            for(int i = 1; i <= 200; i++)
                fa2[tmp][i]=fa2[fa[tmp][0]][i-1];
            for(int i = 1; i <= 200; i++)
                dp[tmp][i]=dp[fa2[tmp][i]][i]^w[tmp];
            for(int i = head[tmp]; i != -1; i = edge[i].next){
                int v = edge[i].to;
                if(v == fa[tmp][0])continue;
                deg[v] = deg[tmp] + 1;
                fa[v][0] = tmp;
                que.push(v);
            }
        }
    }
    int LCA(int u,int v){
        if(deg[u] > deg[v])swap(u,v);
        int hu = deg[u], hv = deg[v];
        int tu = u, tv = v;
        for(int det = hv-hu, i = 0; det ; det>>=1, i++)
            if(det&1)tv = fa[tv][i];
        if(tu == tv)return tu;
        for(int i = DEG-1; i >= 0; i--){
            if(fa[tu][i] == fa[tv][i])continue;
            tu = fa[tu][i];
            tv = fa[tv][i];
        }
        return fa[tu][0];
    }
    bool flag[MAXN];
    
    int go(int x,int step){
        for(int det = step, i = 0; det ; det>>=1, i++)
            if(det&1){
                x = fa[x][i];
                if(x==root) break;
            }
        return x;
    }
    
    int Sum(int x,int step){
        int ret=w[x];
        while(x!=root){
            x=go(x,step);
            ret^=w[x];
        }
        return ret;
    }
    
    
    int main(){
        int T,N,Q;
        int u,v,k;
        while(scanf("%d%d",&N,&Q)!=EOF){
            init();
            memset(dp,0,sizeof(dp));
            memset(w,0,sizeof(w));
            for(int i = 1; i < N; i++){
                scanf("%d%d",&u,&v);
                addedge(u,v);
                addedge(v,u);
            }
            for(int i=1;i<=N;i++) scanf("%d",&w[i]);
            for(int i=1;i<=N;i++) addedge(N+i,N+i-1),addedge(N+i-1,N+i);
            root=N+N;
            BFS(root);
            for(int i=0;i<Q;i++){
                scanf("%d%d%d",&u,&v,&k);
                int ans=0;
                if(u==v){
                    ans=w[u];
                }
                else if(k<=200){
                    int lca=LCA(u,v);
                    int lab=deg[u]+deg[v]-2*deg[lca];
                    int lalca=deg[u]-deg[lca];
                    int yu1=lalca%k,yu2=k-yu1,yu3=lab%k;
                    ans=dp[u][k]^dp[go(lca,yu2)][k]^dp[go(v,yu3)][k]^dp[go(lca,yu1)][k];
                }
                else{
                    int lca=LCA(u,v);
                    int lab=deg[u]+deg[v]-2*deg[lca];
                    int lalca=deg[u]-deg[lca];
                    int yu1=lalca%k,yu2=k-yu1,yu3=lab%k;
                    ans=Sum(u,k)^Sum(go(lca,yu2),k)^Sum(go(v,yu3),k)^Sum(go(lca,yu1),k);
                }
                printf("%d
    ",ans);
            }
        }
        return 0;
    }



  • 相关阅读:
    Deadlock Detecting--转
    java.util.concurrent包详细分析--转
    spring源码分析之spring-core总结篇
    Google和Baidu常用的搜索技巧--转
    极速发展的饿了么订单系统架构演进--转
    唯品会订单分库分表的实践总结以及关键步骤--转
    数据扩展性探讨和总结--转
    MAT使用--转
    Java 8 Stream API详解--转
    论海明威的存在主义宗教意识——存在主义虚无主义。注:部分观点个人不赞同
  • 原文地址:https://www.cnblogs.com/zhangxianlong/p/10672483.html
Copyright © 2011-2022 走看看