博客园 首页 私信博主 显示目录 隐藏目录 管理 动画

LibreOJ β Round #2 F. 数学上来先打表

传送门

题解

 

做法与题解基本无异,不过他说用vector我觉得用链表来得更好一些。

#include<queue>
#include<ctime>
#include<bitset>
#include<vector>
#include<cstdio>
#include<algorithm>
#define MN 110000
using namespace std;

int read_p,read_ca,read_f;
inline int read(){
    read_p=0;read_ca=getchar();read_f=1;
    while(read_ca<'0'||read_ca>'9') {if (read_ca=='-') read_f=-1;read_ca=getchar();}
    while(read_ca>='0'&&read_ca<='9') read_p=read_p*10+read_ca-48,read_ca=getchar();
    return read_p*read_f;
}
struct na{unsigned long long x;int p,ne;}b[MN*5];
int n,m,a[MN],id[MN],Ra[MN],now=0,pos[MN],T,num=0,qn=0,mmh[MN],sz[MN],fa[MN],l[MN],NUM=0,U[1<<16],SS=0;
vector <int> Qx[MN],Qy[MN],Qp[MN],to[MN],x[MN],y[MN];
bool cmp(int x,int y){return a[x]<a[y];}
inline int gf(int x){while(x!=fa[x]) x=fa[x];return x;}
queue<int> q;
inline void add(int x,int y){
    if (x==y) return;
    fa[x]=y;sz[y]+=sz[x];
    for (int A=l[x],*B=&l[y];A!=-1;A=b[A].ne){
        while (b[*B].p<b[A].p&&*B!=-1) B=&b[*B].ne;
        if (*B==-1||b[*B].p>b[A].p){
            int p;if(q.empty())p=NUM++;else p=q.front(),q.pop();
            b[p].x=b[A].x;b[p].p=b[A].p;
            b[p].ne=*B;*B=p;B=&b[p].ne;
        }else b[*B].x^=b[A].x;
    }
}
inline void del(int x,int y){
    if (x==y) return;
    fa[x]=x;sz[y]-=sz[x];
    for (int A=l[x],*B=&l[y];A!=-1;A=b[A].ne){
        while (b[*B].p<b[A].p&&*B!=-1) B=&b[*B].ne;
        b[*B].x^=b[A].x;
        if (!b[*B].x) q.push(*B),*B=b[*B].ne;
    }
}
inline int calc(int x,int y){
    x=gf(x);
    if (sz[x]<y) return -1;
    for (int i=l[x];i!=-1;i=b[i].ne)
    if (y>U[b[i].x>>48]+U[(b[i].x>>32)&65535]+U[(b[i].x>>16)&65535]+U[b[i].x&65535]) y-=U[b[i].x>>48]+U[(b[i].x>>32)&65535]+U[(b[i].x>>16)&65535]+U[b[i].x&65535];else
    for (int j=0;j<64;j++)
    if ((b[i].x>>j)&1) if (!(--y)) return (b[i].p<<6)|j;
}
void dfs(int p){
    for (int i=0;i<Qx[p].size();i++) mmh[Qp[p][i]]=calc(Qx[p][i],Qy[p][i]);
    for (int i=0;i<to[p].size();i++){
        int X=x[p][i],Y=y[p][i];
        if (X==-1) X=Y;
        X=gf(X);Y=gf(Y);
        if (sz[X]>sz[Y]) swap(X,Y);
        add(X,Y);
        dfs(to[p][i]);
        del(X,Y);
    }
}
int main(){
    //freopen("a.in","r",stdin);
    n=read();m=read();
    for (int i=1;i<(1<<16);i++) U[i]=U[i^(-i&i)]+1;
    for (int i=0;i<n;i++) a[i]=read(),id[i]=i,fa[i]=i,sz[i]=1;
    sort(id,id+n,cmp);
    for (int i=0;i<n;i++) l[id[i]]=i,b[i].x=1ull<<(i&63),b[i].p=i>>6,b[i].ne=-1;NUM=n;
    
    for (int i=1;i<=m;i++){
        T=read();
        if (T==1) num++,to[now].push_back(num),x[now].push_back(read()-1),y[now].push_back(read()-1),now=num;else
        if (T==2) now=pos[read()];else Qx[now].push_back(read()-1),Qy[now].push_back(read()),Qp[now].push_back(qn++);
        pos[i]=now;
    }
    dfs(0);
    //freopen("a.out","w",stdout);
    for (int i=0;i<qn;i++) printf("%d\n",mmh[i]==-1?-1:a[id[mmh[i]]]);
}
View Code

 

posted @ 2017-07-04 11:14  swm_sxt  阅读(539)  评论(7编辑  收藏  举报