ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

P3224 [HNOI2012]永无乡

2020-09-27 16:33:28  阅读:229  来源: 互联网

标签:node return nil int 永无 HNOI2012 P3224 inline define


事实证明,没过对拍的代码都不一定是对的,即使你在各大OJ上都AC了。。我写的那个代码,说他漏洞百出一点都不过分,而且拍出来的第一组数据都过不去,但是他竟然能AC。。

这题思路其实挺简单的,一句话题意就是带合并的区间k大,这里的合并用线段树合并和splay启发式合并都可以,我写的是splay。有个结论,splay按照中序遍历合并,复杂度能少一个log。

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
#define forg(i,x) for(int i=first[x];i;i=nxt[i])
#define uu unsigned
#define fi first
#define se second
#define od(x) ((x)&1)
#define ev(x) (od(x)^1)
#define mi2(x) (1<<(x))
#define scanf a1234=scanf
#define fre(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
int a1234;
char buf[1<<18],*bufs=buf,*buft=buf;
inline int gc(){
    return bufs==buft&&(buft=(bufs=buf)+fread(buf,1,1<<18,stdin)),bufs==buft?-1:*bufs++;
}
inline void xxx(){for(;;);}

const int mxn=1e5+3;
int n,m,q,w[mxn];
class unio{
    public:
    int fa[mxn],siz[mxn];
    inline void init(){
        for(int i=1;i<=n;++i)fa[i]=i,siz[i]=1;
    }
    inline int find(int x){
        while(x!=fa[x])x=fa[x]=fa[fa[x]];
        return x;
    }
    inline void merge(int x,int y){
        x=find(x),y=find(y);fa[x]=y,siz[y]+=siz[x];
    }
}us;
#define lch ch[0]
#define rch ch[1]
struct node{
    node*ch[2],*prt;
    int val,siz,xh;
    inline void up(){siz=lch->siz+rch->siz+1;}
}*nil,ap[mxn];
class PSL{
    public:
    node*po[mxn],*rt[mxn];
    inline void init(){
        nil=&ap[0];
        nil->lch=nil->rch=nil->prt=nil;
        nil->siz=0;
        for(int i=1;i<=n;++i)po[i]=newd(i,nil);
        memcpy(rt,po,sizeof(po));
    }
    inline node*newd(int xx,node*f){
        node*p=&ap[xx];
        p->lch=p->rch=nil,p->prt=f,p->val=w[xx],p->xh=xx,p->siz=1;
        return p;
    }
    #define root(x) rt[us.find(x)]
    inline int son(node*x){return x==x->prt->rch;}
    inline void conn(node*x,node*y,int k){x->prt=y,y->ch[k]=x;}
    inline void rotate(node*x){
        node*f=x->prt,*g=f->prt,*&r=root(f->xh);
        int k=son(x),kk=son(f);
        conn(x->ch[k^1],f,k),conn(f,x,k^1);
        if(g==nil)r=x,r->prt=nil;else conn(x,g,kk);
        f->up(),x->up();
    }
    inline void splay(node*x,node*y=nil){
        while(x->prt!=y){
            node*f=x->prt;
            if(f->prt==y)return rotate(x);
            if(son(x)^son(f))rotate(x),rotate(x);
            else rotate(f),rotate(x);
        }
    }
    inline void merge(int x,int y){
        if(us.siz[x]>us.siz[y])swap(x,y);
        node*r=root(x);us.merge(x,y);
        dfs(r,y);
    }
    inline void dfs(node*x,int y){

        if(x->lch!=nil)dfs(x->lch,y),x->lch=nil;
        node*kk=x->rch;
        x->rch=nil,insert(x,y);
        if(kk!=nil)dfs(kk,y);
    }
    inline void insert(node*x,int y){
        node*p=root(y);
        while(1){
            ++p->siz;
            node*&nxt=p->ch[p->val<x->val];
            if(nxt==nil)return nxt=x,nxt->prt=p,splay(nxt);
            p=nxt;
        }
    }
    inline int kth(int d,int x){
        node*p=root(d);
        while(1){
            int num=p->lch->siz;
            if(x==num+1)return splay(p),p->xh;
            if(x<=num)p=p->lch;
            else p=p->rch,x-=num+1;
        }
    }
}sp;
#undef lch
#undef rch
#undef root
int main(){
    scanf("%d%d",&n,&m);for(int i=1;i<=n;++i)scanf("%d",w+i);
    us.init(),sp.init();
    for(int i=1,u,v;i<=m;++i){scanf("%d%d",&u,&v),u=us.find(u),v=us.find(v);if(u==v)continue;sp.merge(u,v);}
    scanf("%d",&q);
    while(q--){
        char o[3];int x,y;scanf("%s%d%d",o,&x,&y);
        if(o[0]=='Q'){
            x=us.find(x);
            if(us.siz[x]<y){puts("-1");continue;}
            printf("%d\n",sp.kth(x,y));
        }else if(o[0]=='B'){
            x=us.find(x),y=us.find(y);
            if(x!=y)sp.merge(x,y);
        }
    }
    return 0;
}


//对拍
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
#define forg(i,x) for(int i=first[x];i;i=nxt[i])
#define uu unsigned
#define fi first
#define se second
#define ran() ((unsigned)rand())
#define lam(z,k) [&](const z &a,const z &b){ return k; }
#define od(x) ((x)&1)
#define ev(x) (od(x)^1)
#define scanf a1234=scanf
#define system a1234=system
#define fp fprintf
int a1234;
inline void xxx(){for(;;);}
inline int rd(int l,int r){return rand()%(r-l+1)+l;}
inline int rd1(int l,int r){--r;return rand()%(r-l+1)+l;}
FILE* fo;
const int mxn=1e5+3;
int n;
typedef vector<int>::iterator vit;
class unio{
    public:
    int fa[mxn],siz[mxn],cnt;
    vector<int>cx;
    inline void init(){
        cnt=n;cx=vector<int>();
        for(int i=1;i<=n;++i)fa[i]=i,siz[i]=1,cx.push_back(i);
    }
    inline int find(int x){
        while(x!=fa[x])x=fa[x]=fa[fa[x]];
        return x;
    }
    inline void merge(int x,int y){
        x=find(x),y=find(y);fa[x]=y,siz[y]+=siz[x];
        --cnt,er(x);
    }
    inline void er(int x){
        cx.erase(lower_bound(cx.begin(),cx.end(),x));
    }
    inline int getan(int x){
        er(x);
        int res=cx[rd1(0,cx.size())];
        cx.insert(lower_bound(cx.begin(),cx.end(),x),x);
        return res;
    }
}us;

int w[mxn];
inline void maked(){
    fo=fopen("te.in","w");
    n=rd(1,10000);
    us.init();
    fp(fo,"%d 0\n",n);
    for(int i=1;i<=n;++i)w[i]=i;
    random_shuffle(w+1,w+n+1);
    for(int i=1;i<=n;++i)fp(fo,"%d ",w[i]);
    fp(fo,"\n");
    int q=rd(1,10000);fp(fo,"%d\n",q);
    for(int i=1;i<=q;++i){
        if(us.cnt>1&&rand()%3){
            int xx=rd(1,n),x=us.find(xx),y=us.getan(x);
            fp(fo,"B %d %d\n",xx,y);
            us.merge(x,y);
            continue;
        }
        int x=rd(1,n),y=rd(1,us.siz[us.find(x)]);
        fp(fo,"Q %d %d\n",x,y);
    }
    puts("ok");
    fclose(fo);
}
inline int work(){
    maked();
    system("./a <te.in >1.ans");
    system("./b <te.in >2.ans");
    return system("diff 1.ans 2.ans -b -B -q");
}
int main(){
    srand((uu)time(0));
//    maked();return system("cat te.in"),3;
    system("g++ ac.cpp -O2 -Wall -o a");
    system("g++ yx.cpp -O2 -Wall -o b");
    int cases=0;
    for(;;){printf("%d\n",++cases);if(work())return 3;if(cases==1000)return 0;}
    return 0;
}

标签:node,return,nil,int,永无,HNOI2012,P3224,inline,define
来源: https://www.cnblogs.com/happyguy/p/13740290.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有