题目描述

输入

输出

样例输入

5 3

1 2 3 1 2

1 2

1 1

1 1

样例输出

4

数据范围

解法

考虑设置左指针l和右指针r;

维护[l,r]的关于等第的桶。

初始l=r=0;

每次右移r,加入新元素a[r];

如果桶因此爆了上限,则右移l并剔除a[l]直至桶不再爆上线。

(“桶爆上限”定义:某一元素的计数超过给定的区间的右端点)

每次右移结束后,如果所有元素的计数位于各自给定区间之内;

则就称这个[l,r]可以对答案进行贡献;


贡献的方式:

假定[l,r]区间内可以对答案进行贡献,

简单想一个O(n)的贡献方法,一直把l向右移直至[l,r]不再可以对答案贡献为止。

考虑优化,显然容易确定对于每种等第最多向右移多少位以保证区间可以进行贡献,设为x[i]。

那么贡献就等于所有x[i]的最小值。

在右移的时候顺便用线段树维护这个x。


题解给出了一种O(n)的方法。

代码

#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
#define ll long long
#define ln(x,y) ll(log(x)/log(y))
#define sqr(x) ((x)*(x))
using namespace std;
const char* fin="survey.in";
const char* fout="survey.out";
const ll inf=0x7fffffff;
const ll maxn=200007,maxt=maxn*4;/*注意!!!!!!!!*/
ll n,m,i,j,k,cnt,head,tmp;
ll ans;
ll a[maxn],tong[maxn],b[maxn][2];
ll c[maxt],fi[maxn],ta[maxn],ne[maxn],key[maxn];
bool bz=false;
void change(ll l,ll r,ll t,ll v,ll v1){
ll mid=(l+r)/2;
if (l==r) {
c[t]=v1;
return;
}
if (v<=mid) change(l,mid,t*2,v,v1);
else change(mid+1,r,t*2+1,v,v1);
c[t]=min(c[t*2],c[t*2+1]);
}
ll getmin(ll l,ll r,ll t,ll v1,ll v2){
ll mid=(l+r)/2;
if (l>v2 || r<v1) return inf;
if (l>=v1 && r<=v2) return c[t];
return min(getmin(l,mid,t*2,v1,v2),getmin(mid+1,r,t*2+1,v1,v2));
}
int main(){
freopen(fin,"r",stdin);
freopen(fout,"w",stdout);
scanf("%d%d",&n,&m);
memset(c,127,sizeof(c));
for (i=1;i<=n;i++) scanf("%d",&a[i]);
for (i=1;i<=m;i++) {
scanf("%d%d",&b[i][0],&b[i][1]);
if (b[i][0]==0) cnt++;
}
head=1;
for (i=1;i<=n;i++){
if (fi[a[i]]==0) fi[a[i]]=ta[a[i]]=i;
else ne[ta[a[i]]]=ta[a[i]]=i;
if (tong[a[i]]>=b[a[i]][0]){
tong[a[i]]++;
if (b[a[i]][0]==0) change(1,m,1,a[i],inf);
else {
key[a[i]]=ne[key[a[i]]],change(1,m,1,a[i],key[a[i]]);
}
while (tong[a[i]]>b[a[i]][1]){
bz=false;
if (tong[a[head]]>=b[a[head]][0]) bz=true;
tong[a[head]]--;
fi[a[head]]=ne[fi[a[head]]];
if (tong[a[head]]<b[a[head]][0] && bz) cnt--;
head++;
}
}else{
tong[a[i]]++;
if (tong[a[i]]==b[a[i]][0]){
cnt++;
key[a[i]]=fi[a[i]];
change(1,m,1,a[i],key[a[i]]);
}
}
if (cnt==m) {
ans+=getmin(1,m,1,1,m)-head+1;
}
}
printf("%lld",ans);
return 0;
}

启发

线性维护区间时,不妨考虑设置左右指针。

再联系数据结构来进行优化。

【JZOJ4804】【NOIP2016提高A组模拟9.28】成绩调研的更多相关文章

  1. 【JZOJ4803】【NOIP2016提高A组模拟9.28】求导

    题目描述 输入 输出 样例输入 2x^2+3x+1 样例输出 4x+3 数据范围 样例解释 求导的意思: 多项式是由若干个单项式构成的 单项式的一般形式是ax^b,其中ab都是常数,x是自变量 对于单 ...

  2. NOIP2016提高A组模拟9.28总结

    这次三道题都是可以AC的. 每道题思路都正确,但每道题都有细节没有注意. 第一题 1.没注意系数为1时可以省略系数: 2.没注意在第一项处理常数后,不能输出+号. 导致丢失20分:一定要多出特殊数据, ...

  3. 【JZOJ4805】【NOIP2016提高A组模拟9.28】跟踪

    题目描述 输入 输出 样例输入 4 2 1 3 1 2 2 3 3 4 样例输出 2 数据范围 解法 预处理出两个陌生人走到各个点的距离. 从石神处开始dfs,判断走到每一个点是否会被抓: 如果会,则 ...

  4. JZOJ 4732. 【NOIP2016提高A组模拟8.23】函数

    4732. [NOIP2016提高A组模拟8.23]函数 (Standard IO) Time Limits: 1500 ms  Memory Limits: 262144 KB  Detailed ...

  5. 【NOIP2016提高A组模拟9.14】数列编辑器

    题目 分析 比赛上,没有注意到询问只询问光标前面,于是只打了个暴力. 因为询问只询问光标前面,首先,当光标向后每移动到一个位置,顺便将这个位置的前缀和,和最大前缀和求出来. 总之,模拟 #includ ...

  6. 【NOIP2016提高A组模拟9.24】总结

    第一题纯模拟,结果那个出题人脑子似乎进水了,空间限制开了1G!!! 导致我捉摸了半天为什么空间要开那么大,最后只能得出上面的结论. 第二题是个矩阵快速幂,比赛上我没把递推式求出来,但是根据各种乱搞,得 ...

  7. 【JZOJ4746】【NOIP2016提高A组模拟9.3】树塔狂想曲

    题目描述 相信大家都在长训班学过树塔问题,题目很简单求最大化一个三角形数塔从上往下走的路径和.走的规则是:(i,j)号点只能走向(i+1,j)或者(i+1,j+1).如下图是一个数塔,映射到该数塔上行 ...

  8. 【JZOJ4745】【NOIP2016提高A组模拟9.3】看电影

    题目描述 听说NOIP2016大家都考得不错,于是CCF奖励省常中了 K 张变形金刚5的电影票奖励OI队的同学去看电影.可是省常中OI队的同学们共有 N(N >= K)人.于是机智的你想到了一个 ...

  9. 【JZOJ4787】【NOIP2016提高A组模拟9.17】数格子

    题目描述 输入 输出 样例输入 1 10000 3 10000 5 10000 0 0 样例输出 1 11 95 数据范围 每个测试点数据组数不超过10组 解法 状态压缩动态规划. 设f[i][j]表 ...

随机推荐

  1. 【bzoj2120】数颜色 带修莫队

    数颜色 题目描述 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画 ...

  2. 第五章 Odoo 12开发之导入、导出以及模块数据

    大多数Odoo 模块的定义,如用户界面和安全规则,实际是存储在对应数据表中的数据记录.模块中的 XML 和 CSV 文件不是 Odoo 应用运行时使用,而是载入数据表的手段.正是因为这个原因,Odoo ...

  3. 如何收缩Mysql的ibdata1文件

    ibdata1是MySQL数据库中一个数据文件了,你会发现它来越大了,下面我来介绍收缩Mysql的ibdata1文件大小方法. 如果你有使用InnoDB来存储你的Mysql表,使用默认设置应该会碰到个 ...

  4. Redis生存时间、删除策略和排序

    生存时间 设置命令 expire key long:设置数据在long秒后过期. pexpire key long:设置数据在long毫秒后过期. ttl key:查询数据剩余的生存时间.如果数据已过 ...

  5. HDFS应用实例

  6. 第02章 Python快速入门

    007.快速入门,边学边用 008.变量类型 print(type(变量))    查看变量的了类型     现在常用的变量的类型有整型.浮点型.字符型 009.List基础模块 类型转换:str(8 ...

  7. lc287 Game of Live

    lc287 Game of Live 难点在于不能使用额外的空间. 观察到数组中每一个元素要么为1要么为0,32位int只用了一位,可以利用bit操作,将第二次state存储到int变量的倒数第二位中 ...

  8. Crontab 入门

    参考网址: http://www.centoscn.com/CentOS/help/2014/0820/3524.html 简单命令 service crond restart //重启crontab ...

  9. Activity、FragmentActivity和AppCompatActivity的区别

    Activity Activity是最基础的一个,是其它类的直接或间接父类. Activity中只能使用系统自带的host Fragment(API Level 11中加入),对应getFragmen ...

  10. navicat修改mysql用户密码,前提是能登陆

    幸亏之前已经连上了数据库后边才忘记密码