2021-08-24 SSL 模拟赛 T2 【莫队】【树状数组】

21-08-24 SSL 模拟赛 T2

原题:【洛谷 P4867 Gty的二逼妹子序列】

依旧没有标题。
2021-08-24 SSL 模拟赛 T2 【莫队】【树状数组】_第1张图片

题目大意:

题目的描述已经够简略了······

思路:

70%:

因为数据太水,直接暴力 O ( n ∗ m ) O(n*m) O(nm) 可以拿70分,但是根据大佬的说法,这 70% 是给主席树的(注意题目中的 l = 1 l=1 l=1)赛时我当然是打了暴力啦。

100%:

如果没有数据所处的范围 [ a , b ] [a,b] [a,b],那么这一道题就是一个莫队的模板题 (比模板还模板)
对于要答案在区间 [ a , b ] [a,b] [a,b]的范围内,我们可以使用一个树状数组在值域上维护答案的前缀和,每走到一个数看看当前是否该数是否第一次出现或者在询问区间内出现次数为0,在树状数组的相应位置 +1,-1 就好了。
剩下的就是莫队的模板了。
时间复杂度 O ( n ∗ n ∗ l o g   n ) O(n*\sqrt n*log~n) O(nn log n) 左右

代码:

#include
#include
#include
#include
#include
#include
#include
#define r register
//#define ull unsigned long long
#define rep(i,x,y) for(r ll i=x;i<=y;++i)
#define per(i,x,y) for(r ll i=x;i>=y;--i)
using namespace std;
typedef long long ll;
const ll V=1e6+10;
ll n,m,p[V/10+1],c[V/10+1],f[V/10+1],cnt[V/10+1];
ll now,ans,maxn;
struct node
{
     
	ll x,y,u,v;
	ll id,val;
}a[V];
inline ll in()
{
     
	ll res=0,f=1;
	char ch;
	while((ch=getchar())<'0'||ch>'9')
	 if(ch=='-') f=-1;
	res=res*10+ch-48;
	while((ch=getchar())>='0'&&ch<='9')
	 res=res*10+ch-48;
	return res*f;
}
inline void put(ll x)
{
     
	if(x<0) putchar('-'),x=-x;
	if(x>9) put(x/10);
	putchar(x%10+48);
}
bool cmp1(node a,node b)
{
     
	if(f[a.x]==f[b.x]) return a.y<b.y;
	return a.x<b.x;
}
bool cmp2(node a,node b)
{
     
	return a.id<b.id;
}
ll lowbit(ll x) {
      return x&(-x); }
void add(ll x,ll y)
{
     
	for(;x<=n;x+=lowbit(x))
	 c[x]+=y;
}
ll ask(ll x)
{
     
	if(x==0) return 0;
	ll res=0;
	for(;x;x-=lowbit(x))
	  res+=c[x];
	return res;
}
void ins(ll x)
{
     
	if(!cnt[x]) add(x,1);
	++cnt[x];
}
void del(ll x)
{
     
	--cnt[x];
	if(!cnt[x]) add(x,-1);
}
void moteam()
{
     
	ll le=0,ri=0;
	rep(i,1,m)
	{
     
		while(le<a[i].x) del(p[le]),++le;
		while(le>a[i].x) --le,ins(p[le]);
		while(ri<a[i].y) ++ri,ins(p[ri]);
		while(ri>a[i].y) del(p[ri]),--ri;
		a[i].val=ask(a[i].v)-ask(a[i].u-1);
	}
}
int main()
{
     
	n=in(),m=in();
	now=sqrt(n);
	rep(i,1,n)
	{
     
		p[i]=in();
		f[i]=(i-1)/now+1;
//		maxn=max(maxn,p[i]);
	}
	rep(i,1,m)
	{
     
		a[i].x=in(),a[i].y=in();
		a[i].u=in(),a[i].v=in();
		a[i].id=i;
	}
//	cout<
	sort(a+1,a+m+1,cmp1);
//	rep(i,1,m)
//	 printf("%lld %lld %lld %lld %lld\n",a[i].id,a[i].x,a[i].y,a[i].u,a[i].v);
	moteam();
	sort(a+1,a+m+1,cmp2);
	rep(i,1,m)
	 put(a[i].val),putchar(10);
	return 0;
}

你可能感兴趣的:(莫队,树形数据结构,#,树状数组,ssl,莫队,树状数组)