P4396 [AHOI2013]作业

P4396 [AHOI2013]作业

题目描述

详见:P4396 [AHOI2013]作业

solution

莫队+树状数组的裸题(莫队+分块,CDQ分治都可以,莫队+线段树大概需要卡常)。

时间复杂度   O(n\sqrt{n}lgn)

Code

#include<bits/stdc++.h>
using namespace std;
const int MAXN=2e5+50;


inline int read()
{
	int f=1,x=0; char c=getchar();
	while (c<'0'||c>'9') { if (c=='-') f=-1; c=getchar(); }
	while (c>='0'&&c<='9') { x=(x<<3)+(x<<1)+(c^48); c=getchar(); }
	return x*f;
}

int n,m,Size,Ans1[MAXN],Ans2[MAXN],a[MAXN],cnt[MAXN];
struct pnode{int l,r,a,b,id,x; } p[MAXN];
struct Tree_Array
{
	int tree[MAXN<<1];
	int lowbit(int x){ return x&(-x); }
	void change(int x,int y) { for (;x<=n;x+=lowbit(x)) tree[x]+=y; }
	int query(int x){ int ans=0; for (;x;x-=lowbit(x)) ans+=tree[x]; return ans; }
} tree1,tree2;
int compare(pnode x,pnode y){ return (x.x<y.x)||(x.x==y.x&&x.r<y.r); }
int main()
{
	n=read(),m=read(),Size=trunc(sqrt(n));
	for (int i=1;i<=n;i++) a[i]=read();
	for (int i=1;i<=m;i++)
	{
		p[i].l=read(),p[i].r=read(),p[i].a=read(),p[i].b=read();
		p[i].id=i,p[i].x=(p[i].l-1)/Size+1;
	}
	sort(p+1,p+m+1,compare);
	
	int L=1,R=0;
	for (int i=1;i<=m;i++)
	{
		while (L<p[i].l) cnt[a[L]]--,tree1.change(a[L],-1),tree2.change(a[L],cnt[a[L]]==0?-1:0),L++;
		while (L>p[i].l) L--,cnt[a[L]]++,tree1.change(a[L], 1),tree2.change(a[L],cnt[a[L]]==1? 1:0);
		while (R<p[i].r) R++,cnt[a[R]]++,tree1.change(a[R], 1),tree2.change(a[R],cnt[a[R]]==1? 1:0);
		while (R>p[i].r) cnt[a[R]]--,tree1.change(a[R],-1),tree2.change(a[R],cnt[a[R]]==0?-1:0),R--;
		
		Ans1[p[i].id]=tree1.query(p[i].b)-tree1.query(p[i].a-1);
		Ans2[p[i].id]=tree2.query(p[i].b)-tree2.query(p[i].a-1);
	}
	for (int i=1;i<=m;i++) printf("%d %d\n",Ans1[i],Ans2[i]);
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值