1. 程式人生 > >BZOJ 3545 peaks (離線版&&在線版)

BZOJ 3545 peaks (離線版&&在線版)

tchar ans max tdi ack mat esp using 原來

離線版

首先將詢問和加邊一起排個序

對每個節點建一棵主席樹,連邊時主席樹合並即可

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<cmath>
using namespace std;
typedef long long ll;

const int maxn = 1000010;

int n,m,q;
int a[maxn],b[maxn],fa[maxn],rt[maxn],ans[maxn],p,tot;
struct Node{ int sz,ls,rs; }t[maxn<<2]; struct Q{ int a,b,c,ok,id; }c[maxn<<2]; int find(int x){ return x==fa[x]?x:fa[x]=find(fa[x]); } bool cmp(Q a,Q b){ if(a.c==b.c) return a.ok<b.ok; // 詢問和添加一起排序,並且保證詢問前添加已全部完成 return a.c<b.c; } void modify(int &i,int l,int
r,int p){ if(!i) i=++tot; // 如果原來存在主席樹節點就用原來的 t[i].sz=1; if(l==r) return; int mid=(l+r)/2; if(p<=mid) modify(t[i].ls,l,mid,p); else modify(t[i].rs,mid+1,r,p); } int query(int i,int l,int r,int k){ if(l==r) return l; int sum=t[t[i].ls].sz; int mid=(l+r)/2; if
(k<=sum) return query(t[i].ls,l,mid,k); else return query(t[i].rs,mid+1,r,k-sum); } int merge(int u,int v){ // 線段樹合並 if(!u||!v) return u|v; else if(!t[u].ls&&!t[u].rs){ t[u].sz+=t[v].sz; return u; }else{ t[u].ls=merge(t[u].ls,t[v].ls); t[u].rs=merge(t[u].rs,t[v].rs); t[u].sz=t[u].sz+t[v].sz; return u; } } ll read(){ ll s=0,f=1; char ch=getchar(); while(ch<0 || ch>9){ if(ch==-) f=-1; ch=getchar(); } while(ch>=0 && ch<=9){ s=s*10+ch-0; ch=getchar(); } return s*f;} int main(){ n=read(),m=read(),q=read(); for(int i=1;i<=n;i++) a[i]=read(),b[i]=a[i],fa[i]=i; sort(b+1,b+1+n); p=unique(b+1,b+1+n)-b-1; for(int i=1;i<=n;i++) a[i]=lower_bound(b+1,b+1+p,a[i])-b; for(int i=1;i<=m;i++) c[i].a=read(),c[i].b=read(),c[i].c=read(),c[i].ok=0; for(int i=m+1;i<=m+q;i++) c[i].a=read(),c[i].c=read(),c[i].b=read(),c[i].ok=1,c[i].id=i-m; sort(c+1,c+1+m+q,cmp); for(int i=1;i<=n;i++) modify(rt[i],1,p,a[i]); for(int i=1;i<=m+q;i++){ if(c[i].ok==0){ int u=find(c[i].a),v=find(c[i].b); if(u!=v){ fa[u]=v; rt[v]=merge(rt[u],rt[v]); } }else{ int u=find(c[i].a); if(t[rt[u]].sz<c[i].b) ans[c[i].id]=-1; else ans[c[i].id]=b[query(rt[u],1,p,t[rt[u]].sz-c[i].b+1)]; // 第 k 大 } } for(int i=1;i<=q;i++){ printf("%d\n",ans[i]); } return 0; }

BZOJ 3545 peaks (離線版&&在線版)