萌新求助可持久化权值线段树
查看原帖
萌新求助可持久化权值线段树
521276
张凯_巨大楼主2021/11/23 16:18
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
int n,m,t;
struct nod
{
	int l,r,v;
};
vector<nod>s;
nod getnew()
{
	return (nod){0,0,0};
}
int v1[200010],v2[200010];
int v[200010],d[200010];
int rt[200010];
bool cmp(int x,int y)
{
	return v1[x]<v1[y];
}
int pre[800010];
void add(int o,int l,int r,int v,int io)
{
	pre[io]=o;
	if(l==r)
	{
		s[o].v++;
		return;
	}
	if(v<=(l+r>>1))
	{
		s[o].l=s.size();
		s.push_back(getnew());
		add(s[o].l,l,(l+r>>1),v,io<<1);
		s[o].r=pre[io<<1|1];
	}
	else
	{
		s[o].r=s.size();
		s.push_back(getnew());
		add(s[o].r,(l+r>>1)+1,r,v,io<<1|1);
		s[o].l=pre[io<<1];
	}
	s[o].v=s[s[o].l].v+s[s[o].r].v;
	//cout<<o<<' '<<l<<' '<<r<<' '<<v<<' '<<io<<endl;
	//cout<<s[o].l<<' '<<s[o].r<<' '<<s[o].v<<endl;
}
int query(int lo,int ro,int l,int r,int k)
{
	if(l==r)
	{
		return l;
	}
	int lv=s[s[lo].l].v-s[s[ro].l].v;
	if(lv<k)
	{
		return query(s[lo].r,s[ro].r,(l+r>>1)+1,r,k-lv);
	}
	return query(s[lo].l,s[ro].l,l,(l+r>>1),k);
}
int main()
{
	s.push_back(getnew());
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		cin>>v1[i];
		v2[i]=i;
	}
	sort(v2+1,v2+n+1,cmp);
	v1[0]=(1<<30);
	for(int i=1;i<=n;i++)
	{
		if(v1[v2[i]]!=v1[v2[i-1]])
		{
			t++;
		}
		v[v2[i]]=t;
		d[t]=v1[v2[i]];
	}
	for(int i=1;i<=n;i++)
	{
		rt[i]=s.size();
		s.push_back(getnew());
		add(rt[i],1,t,v[i],1);
		//cout<<endl;
	}
	while(m--)
	{
		int l,r,k;
		cin>>l>>r>>k;
		cout<<d[query(rt[r],rt[l-1],1,t,k)]<<endl;
	}
	return 0;
}

只能过前2个测试点

2021/11/23 16:18
加载中...