• BZOJ 3123 森林


    题解网上都有。。。

    注意主席树的写法吧。。。我这样写可能空间小点吧。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define maxv 80050
    #define maxe 200050
    using namespace std;
    int testcase,n,m,q,lastans=0,father[maxv],size[maxv],dis[maxv],anc[maxv][20],g[maxv],nume=1,val[maxv],hash[maxv];;
    int root[maxv],ls[maxv*50],rs[maxv*50],sum[maxv*50],x,y,k;
    char type[4];
    int tot=0,cnt=0,lab,times=0,vis[maxv];
    struct edge
    {
        int v,nxt;
    }e[maxe];
    void addedge(int u,int v)
    {
        e[++nume].v=v;e[nume].nxt=g[u];
        g[u]=nume;
    }
    int getfather(int x)
    {
        if (father[x]!=x) father[x]=getfather(father[x]);
        return father[x];
    }
    void build(int pre,int &now,int left,int right,int pos)
    {
        if (!now) now=++tot;sum[now]=sum[pre]+1;
        if (left==right) return;
        int mid=(left+right)>>1;
        if (pos<=mid) {build(ls[pre],ls[now],left,mid,pos);rs[now]=rs[pre];}
        else {build(rs[pre],rs[now],mid+1,right,pos);ls[now]=ls[pre];}
    }
    void dfs1(int x)
    {
        father[x]=lab;vis[x]=1;size[lab]++;
        build(root[anc[x][0]],root[x],1,n,val[x]);
        for (int i=g[x];i;i=e[i].nxt)
        {
            int v=e[i].v;
            if (v==anc[x][0]) continue;
            dis[v]=dis[x]+1;anc[v][0]=x;
            for (int e=1;e<=19;e++) anc[v][e]=anc[anc[v][e-1]][e-1];
            dfs1(v);
        }
    }
    void dfs2(int x)
    {
        build(root[anc[x][0]],root[x],1,n,val[x]);
        for (int i=g[x];i;i=e[i].nxt)
        {
            int v=e[i].v;
            if (v==anc[x][0]) continue;
            dis[v]=dis[x]+1;anc[v][0]=x;
            for (int e=1;e<=19;e++) anc[v][e]=anc[anc[v][e-1]][e-1];
            dfs2(v);
        }
    }
    int lca(int x,int y)
    {
        if (dis[x]<dis[y]) swap(x,y);
        for (int e=19;e>=0;e--)
        {
            if (dis[anc[x][e]]>=dis[y] && anc[x][e])
                x=anc[x][e];
        }
        if (x==y) return x;
        for (int e=19;e>=0;e--)
        {
            if (anc[x][e]!=anc[y][e])
            {
                x=anc[x][e];
                y=anc[y][e];
            }
        }
        return anc[x][0];
    }
    int ask(int t1,int t2,int t3,int t4,int left,int right,int k)
    {
        if (left==right) return left;
        int r=sum[ls[t1]]+sum[ls[t2]]-sum[ls[t3]]-sum[ls[t4]];
        int r1=sum[ls[t1]],r2=sum[ls[t2]],r3=sum[ls[t3]],r4=sum[ls[t4]];
        int mid=(left+right)>>1;
        if (k<=r) return ask(ls[t1],ls[t2],ls[t3],ls[t4],left,mid,k);
        else return ask(rs[t1],rs[t2],rs[t3],rs[t4],mid+1,right,k-r);
    }
    void link(int x,int y)
    {
        int f1=getfather(x),f2=getfather(y);
        if (size[f1]>size[f2]) {swap(f1,f2);swap(x,y);}
        father[f1]=f2;size[f2]+=size[f1];
        dis[x]=dis[y]+1;anc[x][0]=y;for (int e=1;e<=19;e++) anc[x][e]=anc[anc[x][e-1]][e-1];
        dfs2(x);
    }
    int main()
    {
        scanf("%d",&testcase);
        scanf("%d%d%d",&n,&m,&q);
        for (int i=1;i<=n;i++)
        {
            scanf("%d",&val[i]);hash[++cnt]=val[i];
            father[i]=i;
        }
        for (int i=1;i<=m;i++)
        {
            scanf("%d%d",&x,&y);
            addedge(x,y);addedge(y,x);
        }
        sort(hash+1,hash+cnt+1);cnt=unique(hash+1,hash+cnt+1)-hash-1;
        for (int i=1;i<=n;i++) val[i]=lower_bound(hash+1,hash+cnt+1,val[i])-hash;
        times++;
        for (int i=1;i<=n;i++)
        {
            if (vis[i]) continue;
            lab=i;dfs1(i);
        }
        for (int i=1;i<=q;i++)
        {
            scanf("%s",&type);
            if (type[0]=='Q')
            {
                scanf("%d%d%d",&x,&y,&k);
                x^=lastans;y^=lastans;k^=lastans;
                int t=lca(x,y);
                lastans=hash[ask(root[x],root[y],root[t],root[anc[t][0]],1,n,k)];
                printf("%d
    ",lastans);    
            }
            else
            {
                scanf("%d%d",&x,&y);
                x^=lastans;y^=lastans;
                link(x,y);addedge(x,y);addedge(y,x);
            }
        }
        return 0;
    }
  • 相关阅读:
    <img>标签
    <a>标签
    HTML标签类型
    HTML实体
    HTML颜色的三种写法
    HTML绝对路径和相对路径
    HTML基本结构及标签样式
    Java Activiti 工作流引擎 springmvc SSM 流程审批 后台框架源码
    java ssm 后台框架平台 项目源码 websocket IM quartz springmvc
    分批插入数据基于mybatis
  • 原文地址:https://www.cnblogs.com/ziliuziliu/p/6422904.html
Copyright © 2020-2023  润新知