首页 > 其他分享 >【模板】可持久化线段树 2

【模板】可持久化线段树 2

时间:2024-01-26 14:13:16浏览次数:28  
标签:cnt 持久 lc 线段 tr mid ll 模板

就是区间第k大,原题链接
这个是用整体二分做的

这个是用可持久化线段树做的

线段树还是快一点啊

#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline ll read() {
	char c=getchar();ll a=0,b=1;
	for(;c<'0'||c>'9';c=getchar())if(c=='-')b=-1;
	for(;c>='0'&&c<='9';c=getchar())a=a*10+c-48;return a*b;
}
struct Segment{
	ll lc,rc,cnt;
}tr[5000001];
ll n,m,a[2000001],tot,cnt,changed,b[2000001],root[5000001],c[2000001];
map<ll,ll> ma;
ll build(ll l,ll r)
{
	ll p=++tot;
	if(l==r)
	{
		tr[p].cnt=0;
		return p;
	}
	ll mid=l+r>>1;
	tr[p].lc=build(l,mid);
	tr[p].rc=build(mid+1,r);
	tr[p].cnt=tr[tr[p].lc].cnt+tr[tr[p].rc].cnt;
	return p;
}
ll insert(ll now,ll l,ll r,ll x,ll val)
{
	ll p=++tot;
	tr[p]=tr[now];
	if(l==r)
	{
		tr[p].cnt+=val;
		return p;
	}
	ll mid=l+r>>1;
	if(x<=mid)tr[p].lc=insert(tr[now].lc,l,mid,x,val);
	else tr[p].rc=insert(tr[now].rc,mid+1,r,x,val);
	tr[p].cnt=tr[tr[p].lc].cnt+tr[tr[p].rc].cnt;
	return p;
}
ll ask(ll now1,ll now2,ll l,ll r,ll k)
{
	if(l==r)return a[l];
	ll mid=l+r>>1;
	ll lcnt=tr[tr[now1].lc].cnt-tr[tr[now2].lc].cnt;
	if(k<=lcnt)return ask(tr[now1].lc,tr[now2].lc,l,mid,k);
	else return ask(tr[now1].rc,tr[now2].rc,mid+1,r,k-lcnt);
}
int main()
{
//	freopen("2.in","r",stdin);
//	freopen("2.out","w",stdout);
	n=read(),m=read();
	for(ll i=1;i<=n;i++)
		b[i]=a[i]=read();
	sort(a+1,a+1+n);
	int ned=0;ned=1;
	for(int i=2;i<=n;i++)
	{
		if(a[i]!=a[i-1])a[++ned]=a[i];
	}
	for(ll i=1;i<=ned;i++)
		ma[a[i]]=++cnt;
	for(int i=1;i<=n;i++)
	{
		b[i]=ma[b[i]];
//		cout<<b[i]<<' ';
	}
//	cout<<endl;
//	sort(b+1,b+1+n);
	for(ll i=1;i<=n;i++)
	{
		root[i]=insert(root[i-1],1,cnt,b[i],1);
	}
	for(ll i=1;i<=m;i++)
	{
		ll l=read(),r=read(),k=read();
		cout<<ask(root[r],root[l-1],1,cnt,k)<<endl;
	}
	return 0;
}
/*
5 2
1 1 3 2 2
1 3 2
3 5 2

*/

标签:cnt,持久,lc,线段,tr,mid,ll,模板
From: https://www.cnblogs.com/HLZZPawa/p/17989188

相关文章

  • 模板
    #definesandomsigned#definefre(x,y)freopen(#x".in","r",stdin),freopen(#y".out","w",stdout);#include<iostream>#include<cstdio>#include<algorithm>#include<cmath>#include&l......
  • 自定义模板中数据标签
    笔记数据标签(DataTag)只是一种辨识度比较高的文本字符串,样式完全由开发人员自己说了算。比如这样的数据标签“【##日期$$】”,编写代码openDataTag("【##日期$$】")即可返回数据标签对象,进而可以对此数据标签填充数据或设置样式等操作。在实际的Word文档开发中,经常需要自动填充......
  • Legacy (线段树优化建图)
    题目链接:Legacy-洛谷|计算机科学教育新生态(luogu.com.cn)题解:考虑题目中一个点向区间连边,如真的对区间中的每一点分别连边后跑最短路,时间空间都要炸。因为是一个点向区间连边,考虑线段树。1到n构造两颗区间线段数 观察上图(从网上搬的)两颗线段树,一颗入树父亲向儿子连......
  • Auth模板
    Auth模板什么是Auth模块,有什么用?django的auth的模块的使用:auth是集合注册,登录,注销,session多个功能集合在一起的模块使用Auth组件的默认auth_user表常用操作fromdjango.contrib.auth.modelsimportUser#1、创建普通用户User.objects.create_user(username='......
  • P3374 【模板】树状数组 1(线段树)
    【模板】树状数组1题目描述如题,已知一个数列,你需要进行下面两种操作:将某一个数加上x求出某区间每一个数的和输入格式第一行包含两个正整数n,m,分别表示该数列数字的个数和操作的总个数。第二行包含n个用空格分隔的整数,其中第i个数字表示数列第i项的初始值......
  • 根据word模板动态导出word文档
    根据word模板动态导出word文档前置条件:新建一个springboot项目1.引jar包<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><group......
  • 【模板】并查集
    并查集是解决两元素是否属于同一集合,将一个集合合并另一集合的数据结构。具体来说,我们使用数字代替集合,比如集合1,集合2.使用数组f[i]维护元素i属于的集合,比如f[2]=4表示元素2属于集合4。具体我们有以下实现功能的代码1初始化表示集合的数组。cin>>n>>m;for(int......
  • 代码模板
    代码模板数论快速幂intqmi(inta,intb,intp){ intres=1; while(b){ if(b&1)res=res*a%p; a=a*a%p; b>>=1; } returnres;}线性筛法(素数+欧拉函数)intst[N1],pri[N1],cnt,phi[N1];intgetp(intn){ phi[1]=1; for(inti=......
  • P3389 【模板】高斯消元法
    #include<bits/stdc++.h>usingnamespacestd;doublemax(doublea,doubleb){ if(a>=b)returna; if(a<b)returnb;}intn;doublea[1010][1010];doublea1[1010][1010];intmain(){ scanf("%d",&n); for(inti=1;i<=n;i++) { ......
  • P3374 【模板】树状数组 1
    part1#include<bits/stdc++.h>#defineintlonglongusingnamespacestd;structnode1{intl,r,value;};node1node[2000020];inta[500010];voidmt(intp,intl,intr){intmid=(l+r)>>1;node[p].l=l;node[p].r=r;if(l==r)......