Description

我有一个元素个数为\(n\)的整数数组\(a\)和\(Q\)个问题,每个问题有\(x,y\)两个参数,我要数有多少个整数\(K\)满足\(K\)在\(a[x]…a[y]\)中出现了恰好\(K\)次。

题面就这么简单了。

Input

第一行两个整数\(n,Q\),表示数组\(a\)的元素个数和询问数;

接下来一行n给整数,描述数组a;

接下来Q行,每行两个数xi,yi(1<=xi<=yi<=n),表示询问的左右边界;

Output

输出Q行,每行一个整数表示满足询问的K的个数。

Sample Input

7 2

3 1 2 2 3 3 7

1 7

3 4

Sample Output

3

1

Hint

对于30%的数据,\(1 \le n,Q \le 1000\);

对于100%的数据,\(1 \le n,Q \le 100000,1 \le a[i] \le 10^9\);

sb莫队题目。。。1个元素支持\(O(1)\)加入。

#include<cmath>
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
using namespace std; #define maxn (100010)
int N,tot,Q,A[maxn],num[maxn],ans[maxn],lim,size; inline int gi()
{
char ch; int f = 1,ret = 0;
do ch = getchar(); while (!(ch >= '0'&&ch <= '9')&&ch != '-');
if (ch == '-') f = -1,ch = getchar();
do ret = ret*10+ch-'0',ch = getchar(); while (ch >= '0'&&ch <= '9');
return ret*f;
} struct node
{
int l,r,id;
inline void read(int i) { l = gi(),r = gi(); id = i; lim = max(lim,r); }
}query[maxn];
inline bool cmp1(const node &a,const node &b) { return a.l < b.l; }
inline bool cmp2(const node &a,const node &b) { return a.r < b.r; } inline void work()
{
int res = 0,L = query[1].l,R = query[1].r;
for (int i = L;i <= R;++i)
if (A[i] <= N)
{
if (num[A[i]] == A[i]) --res;
if (++num[A[i]] == A[i]) ++res;
}
for (int i = 1;i <= Q;++i)
{
while (R < query[i].r)
{
++R;
if (A[R] <= N)
{
if (num[A[R]] == A[R]) --res;
if (++num[A[R]] == A[R]) ++res;
}
}
while (R > query[i].r)
{
if (A[R] <= N)
{
if (num[A[R]] == A[R]) --res;
if (--num[A[R]] == A[R]) ++res;
}
--R;
}
while (L > query[i].l)
{
--L;
if (A[L] <= N)
{
if (num[A[L]] == A[L]) --res;
if (++num[A[L]] == A[L]) ++res;
}
}
while (L < query[i].l)
{
if (A[L] <= N)
{
if (num[A[L]] == A[L]) --res;
if (--num[A[L]] == A[L]) ++res;
}
++L;
}
ans[query[i].id] = res;
}
} int main()
{
freopen("1364.in","r",stdin);
freopen("1364.out","w",stdout);
N = gi(); Q = gi();
for (int i = 1;i <= N;++i) A[i] = gi();
for (int i = 1;i <= Q;++i) query[i].read(i);
size = ceil(sqrt(lim)+0.5);
sort(query+1,query+Q+1,cmp1);
for (int i = 1,j;i <= Q;i = j+1)
{
for (j = i;j < Q&&query[j+1].l - query[i].l <= size;++j);
sort(query+i,query+j+1,cmp2);
}
work();
for (int i = 1;i <= Q;++i) printf("%d\n",ans[i]);
fclose(stdin); fclose(stdout);
return 0;
}

sjtu1364 countcountcount的更多相关文章

随机推荐

  1. javascript优化工具 Doloto

    Doloto是“Download Time Optimizer”的简写.官方页面上说它对于大型复杂的AJAX应用尤其的有用,因为这些应用包含了大量的 JavaScript 代码.简单的说,它的工作原理 ...

  2. Redis常见问题及处理方法

    一.Redis状态检查 唯一标记一个redis实例的是ip和端口,前端是用tcp方式来访问redis的,我们提供给应用访问的是一个ip+63379(一般使用63379) 端口.因此我们执行如下命令检查 ...

  3. C#控制台输入

    学习C语言后,在学习C#会有一个很不适应的小毛病.那就是在C语言里面你可以在一行输入好几个数字或是字母然后分别赋给相应的变量.可是在C#里面就不一样了,它只能读取一行.要实现一个一个变量赋值那就只有一 ...

  4. 《编写高质量代码》CSS部分总结

    如何组织CSS 三层结构:base+common+page 分层目的:减少代码量:便于多人开发和维护 1.base层 最底层,一般设置文件为只读,与具体的UI无关,提供: reset功能.因为浏览器对 ...

  5. ORM中去除反射,添加Expression

    之前接触了别人的ORM框架,感觉牛掰到不行,然后试着自己来写自己的ORM. 最初从园子里找到其他人写的反射的例子: List<PropertyInfo> pis = typeof(T).G ...

  6. 序列化和反序列化(C#)

    有时候我们希望把类的实例保存下来,以便以后的时候用.一个直观的方法就是StreamWriter把类写成一行,用\t分隔开每个属性,然后用StreamReader读出来. 但是这样太麻烦,代码行数较多, ...

  7. Asp.net MVC 4 Attributes特性

    Attributes特性 ActionFilterAttribute Represents the base class for filter attributes. 代表筛选器属性的基类. Acti ...

  8. MongoDB下载安装

    MongoDB官方下载地址:http://www.mongodb.org/ 一.在Windows平台下的安装 1.下载MongoDB数据库 2.设置MongoDB程序存放目录 下载完数据库后,直接解压 ...

  9. 策略模式(Strategey Pattern)

    策略模式:定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户. 下面举个例子: 有两个具体策略,分别执行两个整型加法和减法. interface Strateg ...

  10. SharePoint2013TimerJob计时器发送邮件

    http://www.3fwork.com/b500/000307MYM008190/