• P5064 [Ynoi2014] 等这场战争结束之后


    P5064 [Ynoi2014] 等这场战争结束之后(值域分块+并查集)

    建出操作树,离散化,然后并查集+值域分块维护。

    代码:

    #include<bits/stdc++.h>
    #define PII pair<int,int>
    using namespace std;
    template <typename T>
    inline void read(T &x){
    	x=0;bool f=false;char ch=getchar();
    	while(!isdigit(ch)){if(ch=='-'){f=true;}ch=getchar();}
    	while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    	x=f?-x:x;
    	return ;
    }
    template <typename T>
    inline void write(T x){
    	if(x<0) putchar('-'),x=-x;
    	if(x>9) write(x/10);
    	putchar(x%10^48);
    	return ;
    }
    const int N=1e5+5,M=36;
    int n,m,a[N],fa[N],siz[N],B,t=2778,id[N],RES[N],head[N],idx,top;
    short int s[N][M+2];
    struct edge{int v,nex;}e[N];
    struct opt{int op,x,y;}p[N];
    int Getfa(int x){if(x==fa[x])return x;return Getfa(fa[x]);}
    PII stk[N];
    void Merge(int x,int y){
    	x=Getfa(x),y=Getfa(y);
    	if(x==y) return ;
    	if(siz[x]<siz[y]) swap(x,y);
    	fa[y]=x,siz[x]+=siz[y];
    	for(int now=0;now<=B;now++) s[x][now]+=s[y][now];
    	stk[++top]=make_pair(x,y);
    	return ;
    }
    void Delete(int p){
    	while(p--){
    		PII x=stk[top--];siz[x.first]-=siz[x.second],fa[x.second]=x.second;
    		for(int now=0;now<=B;now++) s[x.first][now]-=s[x.second][now];
    	}
    	return ;
    }
    int Query(int x,int y){
    	x=Getfa(x);
    	if(y>siz[x]) return -1;
    	int pos=0;
    	while(s[x][pos]<y){
    		y-=s[x][pos];
    		pos++;
    	}
    	for(int now=0;now<t;now++){
    		if(Getfa(id[pos*t+now])==x) y--;
    		if(y==0) return a[id[pos*t+now]]; 
    	}
    }
    void Add(int u,int v){e[++idx].v=v;e[idx].nex=head[u];head[u]=idx;}
    bool cmp(int x,int y){return a[x]<a[y];}
    void Dfs(int x){
    	int Top=top;
    	if(p[x].op==1) Merge(p[x].x,p[x].y);
    	else if(p[x].op==3){RES[x]=Query(p[x].x,p[x].y);}
    	for(int now=head[x];now;now=e[now].nex){int y=e[now].v;Dfs(y);}
    	if(p[x].op==1){int len=top-Top;Delete(len);}
    }
    int main(){
    	read(n),read(m);
    	B=(n/t)+1;
    	for(int now=1;now<=n;now++) read(a[now]),id[now]=now;
    	sort(id+1,id+n+1,cmp); 
    	for(int now=1;now<=n;now++) fa[now]=now,s[id[now]][(now/t)]=siz[now]=1;
    	for(int now=1;now<=m;now++){
    		read(p[now].op),read(p[now].x);
    		if(p[now].op==2) Add(p[now].x,now);
    		else read(p[now].y),Add(now-1,now);
    	}
    	Dfs(0);	
    	for(int now=1;now<=m;now++) if(p[now].op==3) write(RES[now]),putchar('
    ');
    	return 0;
    }
    
  • 相关阅读:
    stm32学习(一)
    linux驱动之ioctl
    request_threaded_irq()参数
    驱动初步学习
    linux命令操作
    Shell
    进程模块管理
    bash及正规表示法
    python脚本
    Python系统模块os
  • 原文地址:https://www.cnblogs.com/Akmaey/p/14667376.html
Copyright © 2020-2023  润新知