【刷题】BZOJ 3551 [ONTAK2010]Peaks加强版

Description

【题目描述】同3545

Input

第一行三个数N,M,Q。

第二行N个数,第i个数为h_i

接下来M行,每行3个数a b c,表示从a到b有一条困难值为c的双向路径。

接下来Q行,每行三个数v x k,表示一组询问。v=v xor lastans,x=x xor lastans,k=k xor lastans。如果lastans=-1则不变。

Output

同3545

Sample Input

Sample Output

HINT

【数据范围】同3545

这里附上3545:

Description

在Bytemountains有N座山峰,每座山峰有他的高度h_i。有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走,现在有Q组询问,每组询问询问从点v开始只经过困难值小于等于x的路径所能到达的山峰中第k高的山峰,如果无解输出-1。

Input

第一行三个数N,M,Q。

第二行N个数,第i个数为h_i

接下来M行,每行3个数a b c,表示从a到b有一条困难值为c的双向路径。

接下来Q行,每行三个数v x k,表示一组询问。

Output

对于每组询问,输出一个整数表示答案。

Sample Input

10 11 4

1 2 3 4 5 6 7 8 9 10

1 4 4

2 5 3

9 8 2

7 8 10

7 1 4

6 7 1

6 4 8

2 1 5

10 8 10

3 4 7

3 4 6

1 5 2

1 5 6

1 5 8

8 9 2

Sample Output

6

1

-1

8

HINT

【数据范围】

N<=10^5, M,Q<=5*105,h_i,c,x<=109。

Solution

kruskal重构树

重构出来后要找一棵子树中权值第 \(k\) 大,用主席树维护就好了

#include<bits/stdc++.h>
#define ui unsigned int
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
const int MAXN=100000+10,MAXM=500000+10,inf=0x3f3f3f3f;
int n,m,q,e,beg[MAXN<<1],nex[MAXN<<2],to[MAXN<<2],st[MAXN<<1],ed[MAXN<<1],cnt,nt,Jie[20][MAXN<<1],h[MAXN<<1],fa[MAXN<<1],lastans,P[MAXN];
std::vector<int> V;
std::map<int,int> M;
struct node{
int u,v,k;
inline bool operator < (const node &A) const {
return k<A.k;
};
};
node side[MAXM];
#define Mid ((l+r)>>1)
#define lson l,Mid
#define rson Mid+1,r
struct ChairMan_Tree{
int sum[MAXN<<5],lc[MAXN<<5],rc[MAXN<<5],root[MAXN<<1],cnt;
inline void Build(int &rt,int l,int r)
{
sum[rt=++cnt]=0;
if(l==r)return ;
else Build(lc[rt],lson),Build(rc[rt],rson);
}
inline void Update(int &rt,int last,int l,int r,int ps)
{
sum[rt=++cnt]=sum[last]+1;
lc[rt]=lc[last];
rc[rt]=rc[last];
if(l==r)return ;
else
{
if(ps<=Mid)Update(lc[rt],lc[last],lson,ps);
else Update(rc[rt],rc[last],rson,ps);
}
}
inline int Query(int now,int last,int l,int r,int k)
{
if(l==r)return l;
else
{
int t=sum[rc[last]]-sum[rc[now]];
if(k<=t)return Query(rc[now],rc[last],rson,k);
else return Query(lc[now],lc[last],lson,k-t);
}
}
};
ChairMan_Tree T;
#undef Mid
#undef lson
#undef rson
template<typename T> inline void read(T &x)
{
T data=0,w=1;
char ch=0;
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')w=-1,ch=getchar();
while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
x=data*w;
}
template<typename T> inline void write(T x,char ch='\0')
{
if(!x)putchar(48);
static int sta[45],tp;
for(tp=0;x;x/=10)sta[++tp]=x%10;
for(;tp;putchar(sta[tp--]^48));
if(ch!='\0')putchar(ch);
}
template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
template<typename T> inline T min(T x,T y){return x<y?x:y;}
template<typename T> inline T max(T x,T y){return x>y?x:y;}
inline int found(int x)
{
if(fa[x]!=x)fa[x]=found(fa[x]);
return fa[x];
}
inline void insert(int x,int y)
{
to[++e]=y;
nex[e]=beg[x];
beg[x]=e;
}
inline void dfs(int x)
{
st[x]=++nt;
if(x<=n)T.Update(T.root[nt],T.root[nt-1],1,n,h[x]);
else T.root[nt]=T.root[nt-1];
for(register int i=beg[x];i;i=nex[i])
if(to[i]==Jie[0][x])continue;
else dfs(to[i]);
ed[x]=nt;
}
inline void discretization()
{
for(register int i=1;i<=n;++i)V.push_back(h[i]);
std::sort(V.begin(),V.end());
V.erase(std::unique(V.begin(),V.end()),V.end());
for(register int i=0,lt=V.size();i<lt;++i)M[V[i]]=i+1,P[i+1]=V[i];
for(register int i=1;i<=n;++i)h[i]=M[h[i]];
}
inline void init()
{
discretization();
cnt=n;h[0]=inf;
for(register int i=1;i<=n+n-1;++i)fa[i]=i;
std::sort(side+1,side+m+1);
for(register int i=1,u,v;i<=m;++i)
{
u=found(side[i].u),v=found(side[i].v);
if(u==v)continue;
else
{
cnt++;h[cnt]=side[i].k;
insert(cnt,u);insert(u,cnt);
insert(cnt,v);insert(v,cnt);
fa[u]=fa[v]=Jie[0][u]=Jie[0][v]=cnt;
}
}
T.Build(T.root[0],1,n);
for(register int i=1;i<=cnt;++i)
if(!st[i])dfs(found(i));
for(register int j=1;j<=19;++j)
for(register int i=1;i<=cnt;++i)Jie[j][i]=Jie[j-1][Jie[j-1][i]];
}
inline int Get(int v,int x)
{
for(register int i=19;i>=0;--i)
if(h[Jie[i][v]]<=x)v=Jie[i][v];
return v;
}
int main()
{
read(n);read(m);read(q);
for(register int i=1;i<=n;++i)read(h[i]);
for(register int i=1,u,v,k;i<=m;++i)
{
read(u);read(v);read(k);
side[i]=(node){u,v,k};
}
init();
while(q--)
{
int v,x,k;read(v);read(x);read(k);
if(lastans!=-1)v^=lastans,x^=lastans,k^=lastans;
int ps=Get(v,x);
if(ps==v||k>T.sum[T.root[ed[ps]]]-T.sum[T.root[st[ps]-1]])printf("%d\n",lastans=-1);
else write(lastans=P[T.Query(T.root[st[ps]-1],T.root[ed[ps]],1,n,k)],'\n');
}
return 0;
}
上一篇:BZOJ.3551.[ONTAK2010]Peaks加强版(Kruskal重构树 主席树)


下一篇:3551: [ONTAK2010]Peaks加强版