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. 一些ecplise 快捷键

    1 F5:下一步,可以进入下一个函数栈 2 F6:当前函数的下一步,不会进入其他的函数. 3 F8:下一个断点. 4 选中一个变量或者表达式,按ctrl+shift+i 来查看内容或者添加监视的方式. ...

  2. [转]oracle odp.net 32位/64位版本的问题

    本文转自:http://www.cnblogs.com/yjmyzz/archive/2011/04/19/2020793.html 如果你的机器上安装了odp.net,且确信machine.conf ...

  3. Magento中直接使用SQL语句

    原理: magento是基于Zend Framework的,所以底层用的还是zend的zend db 在文件app/code/core/Mage/Catalog/model/Resource/Eav ...

  4. JavaScript设计模式(一)

    使用JavaScript框架和库过程中, 我遇到过很多感觉上'奇形怪状'的代码. 大多数情况下, 按照惯例编写代码也能够写出很多出色的功能. 但是如果不从根本上理解它们实现的方法, 就没办法完全充分发 ...

  5. SSH免密码登录设置

    我们使用ssh-keygen在ServerA上生成private和public密钥,将生成的public密钥拷贝到远程机器ServerB上后,就可以使用ssh命令无需密码登录到另外一台机器Server ...

  6. linux 文本编辑器 vim 基本操作

    三种模式之间转换: 一般模式 可用于光标移动.复制粘贴.查找替换 "vim.txt"表示文件名 8L 表示8行 , 80C 表示80个字符 移动光标常用操作: h .j. k. l ...

  7. GCD 多线程

    Grand Central Dispatch (GCD)是Apple开发的一个多核编程的较新的解决方法.它主要用于优化应用程序以支持多核处理器以及其他对称多处理系统.它是一个在线程池模式的基础上执行的 ...

  8. JavaScript中事件绑定的方法总结

    最近收集了一些关于JavaScript绑定事件的方法,汇总了一下,不全面,但是,希望便于以后自己查看. JavaScript中绑定事件的方法主要有三种: 1 在DOM元素中直接绑定 2 JavaScr ...

  9. WPF设置窗口模式(Windowstyle=“None”)

    当WindowStyle="None"时,设置AllowsTransparency="True",则不会出现黑色Border,然后可以另外设置外边的Border ...

  10. c++中动态尾随内存的技巧和定位new

    c 和 c++ 最大的特点就是对内存的自由操作,数据类型,其实都是对内存的一种解释方式.C语言中常用的一个技巧就是尾随数据,网络编程中经常会用到这个特性, 特别是以前写完成端口的时候,这个特性肯定是会 ...