您的位置:首页 > 其它

3545: [ONTAK2010]Peaks 启发式合并treap 离线处理

2016-02-27 14:52 197 查看
《多年的心头大恨终于解决了系列》

一个半月前写的splay挂了。。于是来写了一发treap,好慢。。

离线随便搞。

听说有强制在线版本?

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#define N 100005
#define M 500005
using namespace std;
int n,m,Q,tmp;
int ls
,rs
,val
,h
,size
,rnd
,f
,root
;
struct node {int x,y,z,id,ans;} e[M],q[M];
inline int read()
{
int a=0,f=1; char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
return a*f;
}
inline bool cmp(node a,node b)
{
return a.z<b.z;
}
inline bool cmp0(node a,node b)
{
return a.id<b.id;
}
int find(int i)
{
return f[i]==i?i:f[i]=find(f[i]);
}
inline void pushup(int k)
{
size[k]=size[ls[k]]+size[rs[k]]+1;
}
inline void lturn(int &k)
{
int t=rs[k]; rs[k]=ls[t]; ls[t]=k; pushup(k); pushup(t); k=t;
}
inline void rturn(int &k)
{
int t=ls[k]; ls[k]=rs[t]; rs[t]=k; pushup(k); pushup(t); k=t;
}
inline void insert(int &k,int v,int id)
{
if (!k)
{
k=id;
val[k]=v;
rnd[k]=rand();
size[k]=1;
return;
}
size[k]++;
if (v<=val[k])
{
insert(ls[k],v,id);
if (rnd[ls[k]]<rnd[k]) rturn(k);
}
else
{
insert(rs[k],v,id);
if (rnd[rs[k]]<rnd[k]) lturn(k);
}
}
void add(int x,int &y)
{
if (!x) return;
add(ls[x],y);
add(rs[x],y);
ls[x]=rs[x]=0;
insert(y,h[x],x);
}
inline void merge(int x,int y)
{
if (size[root[x]]>size[root[y]]) swap(x,y);
f[x]=y;
add(root[x],root[y]);
}
void query(int k,int rank)
{
if (size[ls[k]]+1==rank) tmp=val[k];
else if (size[ls[k]]+1>rank) query(ls[k],rank);
else query(rs[k],rank-size[ls[k]]-1);
}
int main()
{
n=read(); m=read(); Q=read();
for (int i=1;i<=n;i++) h[i]=read();
for (int i=1;i<=m;i++)
e[i].x=read(),e[i].y=read(),e[i].z=read();
for (int i=1;i<=Q;i++)
q[i].x=read(),q[i].z=read(),q[i].y=read(),q[i].id=i;
sort(e+1,e+m+1,cmp);
sort(q+1,q+Q+1,cmp);
for (int i=1;i<=n;i++) f[i]=i;
for (int i=1;i<=n;i++) insert(root[i],h[i],i);
int now=1;
for (int i=1;i<=Q;i++)
{
while (e[now].z<=q[i].z&&now<=m)
{
int p=find(e[now].x),q=find(e[now].y);
if (p!=q) merge(p,q);
now++;
}
int p=find(q[i].x);
if (size[root[p]]<q[i].y) q[i].ans=-1;
else
{
int rank=size[root[p]]-q[i].y+1;
query(root[p],rank);
q[i].ans=tmp;
}
}
sort(q+1,q+Q+1,cmp0);
for (int i=1;i<=Q;i++) printf("%d\n",q[i].ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: