SP3267 DQUERY 解题报告

SP3267 DQUERY 解题报告

题目描述

给出一个长度为n 的数列,$a_{1} ,a_{2},…,a_{n} ,有 q 个询问,每个询问给出数对 ( i , j ) , 需要你给出 ,有q 个询问,每个询问给出数对(i,j),需要你给出 ,有q个询问,每个询问给出数对(i,j),需要你给出a_{i},a_{i+1} ,…,a_{j}$ 这一段中有多少不同的数字

思路

很明显的是,这道题和这道题是完全一样的,但是!!!这个题不会卡莫队

嘿嘿嘿

然后我就把被P1972卡掉的莫队放到这里,然后就过了

P1972题解链接

说句闲话,莫队真好用

代码

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#define maxn 1100000
using namespace std;
int c[maxn],col[maxn],ans;
int n,m,len;
int num[maxn];
inline int read(){
	register int x=0,t=1;
      register char ch=getchar();
      while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
      if(ch=='-'){t=-1;ch=getchar();}
      while(ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
      return x*t;
}
struct Query{
	int l,r,in,id;
	inline bool operator < (const Query &a)const{
		if(!(in^a.in)){
			return (in&1)?r<a.r:r>a.r;
		}
		return in<a.in;
	}
}q[maxn];
inline void change(int x,int k){
	col[c[x]]+=k;
	if(col[c[x]]==0&&k==-1)--ans;
	if(col[c[x]]==1&&k==+1)++ans;
}
int main(){
	n=read();
	len=sqrt(n);
	for(register int i=1;i<=n;i++){
		c[i]=read();
	}
	m=read();
	for(register int i=1;i<=m;i++){
		q[i].l=read();
		q[i].r=read();
		q[i].in=(q[i].l-1)/len+1;
		q[i].id=i;
	}
	sort(q+1,q+1+m);
	int l=1,r=0;
	for(register int i=1;i<=m;i++){
		while(l<q[i].l)change(l,-1),l++;
		while(l>q[i].l)change(l-1,1),l--;
		while(r<q[i].r)change(r+1,1),r++;
		while(r>q[i].r)change(r,-1),r--;
		num[q[i].id]=ans;
	}
	for(register int i=1;i<=m;i++){
		printf("%d\n",num[i]);
	}
	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值