zoukankan      html  css  js  c++  java
  • 【刷题】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='')
    {
    	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!='')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
    ",lastans=-1);
    		else write(lastans=P[T.Query(T.root[st[ps]-1],T.root[ed[ps]],1,n,k)],'
    ');
    	}
    	return 0;
    }
    
  • 相关阅读:
    leetcode ZigZag conversion(mediium) /java
    leetcode longest palindromic substring (medium) /java
    leetcode longest substring without repeating characters(medium) /java
    leetcode two_sum (easy) /java
    think_in_java_多态
    java复用类知识
    java找不到或无法加载主类
    java程序包不存在
    集合
    列表的增删改查
  • 原文地址:https://www.cnblogs.com/hongyj/p/9417837.html
Copyright © 2011-2022 走看看