码迷,mamicode.com
首页 > 其他好文 > 详细

题解 SP23776 KQUERYO - K-Query Online

时间:2020-12-09 11:49:34      阅读:4      评论:0      收藏:0      [点我收藏+]

标签:题解   query   reg   sdi   href   main   online   存在   https   

SP23776

题意:

给出一个长度为 \(n\) 的序列,\(q\) 个询问,询问 \([i,j]\) 区间大于 \(k\) 的数的个数,强制在线

做法:

其实就是这题的强制在线版

很裸的一道主席树,甚至可以说是模板题,直接上主席树的板子即可

查询时如果\(k>mid\),说明左儿子中的数都比\(k\)要小,那么直接到右儿子中查询

如果\(k \le mid\),则说明右儿子中的数都比\(k\)要大,那么直接加上右儿子的贡献,再向左儿子继续递归

同时要注意当\(l = r\)时当前节点维护的就是等于\(k\)的个数,所以直接返回\(0\)就行了

离散化?不存在的

代码:

#include <cstdio>

using namespace std;

#define il inline
#define re register

const int N=3e4+10;
const int K=1e9;

namespace FastIO
{
char buf[1<<21],buf2[1<<21],*p1=buf,*p2=buf;
int p4,p3=-1;
il int getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
il void flush(){fwrite(buf2,1,p3+1,stdout),p3=-1;}
#define isdigit(ch) (ch>=48&&ch<=57)
template <typename T>
il void read(T &x)
{
	re int f=0;x=0;re char ch=getc();
	while(!isdigit(ch)) f|=(ch==‘-‘),ch=getc();
	while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getc();
	x=f?-x:x;
}
template <typename T>
il void print(T x)
{
	if(p3>(1<<20)) flush();
	if(x<0) buf2[++p3]=45,x=-x;
	re int a[50]={};
	do{a[++p4]=x%10+48;}while(x/=10);
	do{buf2[++p3]=a[p4];}while(--p4);
	buf2[++p3]=‘\n‘;
}
}
using namespace FastIO;
//IO优化

int n,m;

int rt[N],pool;
int cnt[N<<5],ls[N<<5],rs[N<<5];
il void insert(int pre,int &now,int l,int r,int x)
{
	now=++pool;
	ls[now]=ls[pre];
	rs[now]=rs[pre];
	cnt[now]=cnt[pre]+1;
	if(l==r) return;
	re int mid=(l+r)>>1;
	if(x>mid) insert(rs[pre],rs[now],mid+1,r,x);
	else insert(ls[pre],ls[now],l,mid,x);
	return;
}
il int query(int pre,int now,int l,int r,int k)
{
	if(!now||l==r) return 0;
	re int mid=(l+r)>>1;
	if(k>mid) return query(rs[pre],rs[now],mid+1,r,k);
	else return cnt[rs[now]]-cnt[rs[pre]]+query(ls[pre],ls[now],l,mid,k);
}
//套板子

int main()
{
	read(n);
	for(re int i=1,x;i<=n;++i) read(x),insert(rt[i-1],rt[i],1,K,x);
    //初始建树
	read(m);re int l,r,k,lst=0;
	while(m--)
	{
		read(l);read(r);read(k);
		l^=lst;r^=lst;k^=lst;
		if(l<1) l=1;if(r>n) r=n;
        //注意!!!
		if(l>r) print(lst=0);
		else print(lst=query(rt[l-1],rt[r],1,K,k));
	}
	flush();return 0;
}

题解 SP23776 KQUERYO - K-Query Online

标签:题解   query   reg   sdi   href   main   online   存在   https   

原文地址:https://www.cnblogs.com/watermonster1y1/p/14086489.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!