zoukankan      html  css  js  c++  java
  • poj2895

    题解:

    splay,维护当前第k大

    并查集维护当前集合

    合并x,y时,del(num[x]),del(num[y]),insert(num[x]+num[y])

    代码:

    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int N=400005;
    int pre[N],tot,xx,q,size[N],c[N][2],fa[N],data[N],root,n,m,x,y,num[N];
    void rot(int x)
    {
        int y=pre[x],k=(c[y][0]==x);
        size[y]=size[c[y][k]]+size[c[x][k]]+1;
        size[x]=size[c[x][!k]]+size[y]+1;
        c[y][!k]=c[x][k];
        pre[c[y][!k]]=y;
        pre[x]=pre[y];
        if(pre[y])c[pre[y]][c[pre[y]][1]==y]=x;
        c[x][k]=y;pre[y]=x;
    }
    void splay(int x,int g)
    {
        for(int y=pre[x];y!=g;rot(x),y=pre[x])
         if(pre[y]!=g)rot((x==c[y][0])==(y==c[pre[y]][0])?y:x);
        if(g==0)root=x;
    }
    void insert(int x)
    {
        int y=root;
        while(c[y][x>data[y]]) y=c[y][x>data[y]];
        data[++tot]=x;
        c[tot][0]=c[tot][1]=0;
        pre[tot]=y;
        if(y)c[y][x>data[y]]=tot;
        splay(tot,0);
    }
    void del(int x)
    {
        int y=root;
        while(data[y]!=x) y=c[y][x>data[y]];
        splay(y,0);
        y=c[root][1];
        bool b;
        if(!y) b=1,y=c[root][0];else b=0;
        while(c[y][b]) y=c[y][b];
        splay(y,root);
        c[y][b]=c[root][b];pre[c[root][b]]=y;pre[y]=0;root=y;
        size[y]=size[c[y][!b]]+size[c[y][b]];
    }
    int find(int x)
    {
        if (x==fa[x])return x;
        return fa[x]=find(fa[x]);
    }
    int findkth(int x)
    {
        int y=root;
        while(x)
        if(size[c[y][0]]+1<x)x-=size[c[y][0]]+1,y=c[y][1];
        else if(size[c[y][0]]+1==x) return data[y];
        else y=c[y][0];
        return data[y];
    }
    int read()
    {
        char c;int x=0;
        for (;c<'0'||c>'9';c=getchar());
        for (;c>='0'&&c<='9';c=getchar())x=x*10+c-48;
        return x;
    }
    void write(int x)
    {
        if (x>=10)write(x/10);
        putchar(x%10+48);
    }
    int main()
    {
        n=read();m=read();
        for (int i=1;i<=n;i++)insert(1);
        for (int i=1;i<=n;i++)fa[i]=i,num[i]=1;
        while (m--)
         {
             xx=read();
             if (xx==0)
              {
                  x=read();y=read();
                  int dx=find(x),dy=find(y);
                  if (dx!=dy)
                 {
                     fa[dx]=dy;
                     del(num[dy]);del(num[dx]);
                     num[dy]+=num[dx];
                     insert(num[dy]);
                     n--;
                 }
             }
            else 
             {
                x=read();
                write(findkth(n-x+1)),puts("");
             }
         }
    }
  • 相关阅读:
    atomic,nonatomic
    iOS开发-retain/assign/strong/weak/copy/mutablecopy/autorelease区别
    MagicalRecord的使用(第三方库实现的数据库)
    深浅拷贝
    C中的预编译宏定义
    省电的iPhone定位
    ASP连接读写ACCESS数据库实例(转)
    【摘要】JavaScript 的性能优化:加载和执行
    PC端网站跳转手机端网站
    多行未知文本垂直居中
  • 原文地址:https://www.cnblogs.com/xuanyiming/p/7886792.html
Copyright © 2011-2022 走看看