题目描述

输入

输出

样例输入

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. csp-s模拟测试52平均数,序列题解

    题面:https://www.cnblogs.com/Juve/articles/11602244.html 平均数: 第k个平均数不好求,我们考虑二分,转化成平均数小于x的有几个 虑把序列中的每个数 ...

  2. transform函数

    C++学习[原创]transform函数的应用 transform(first,last,result,op);//first是容器的首迭代器,last为容器的末迭代器,result为存放结果的容器, ...

  3. Django项目:CMDB(服务器硬件资产自动采集系统)--08--06CMDB测试Linux系统采集硬件数据的命令03

    https://www.virtualbox.org/wiki/Downloads https://mirrors.aliyun.com/centos/7/isos/x86_64/ http://ww ...

  4. js 设置缓存

    长期存储    localStorage.getItem("key");       //获取键的值    localStorage.setItem("key" ...

  5. light oj 1071 dp(吃金币升级版)

    #include <iostream> #include <algorithm> #include <cstring> #include <cstdio> ...

  6. Java虚拟机原理图解-- 1.2、class文件中的常量池

    了解JVM虚拟机原理 是每一个Java程序员修炼的必经之路.但是由于JVM虚拟机中有很多的东西讲述的比较宽泛,在当前接触到的关于JVM虚拟机原理的教程或者博客中,绝大部分都是充斥的文字性的描述,很难给 ...

  7. IDEA工具实现反编译操作

    1.File - Settings... 2.在搜索框中输入“byte” - 勾选 Java Byte code Decompiler选项 点击 OK 键 3.弹出重启IDEA的选择框 选择“rest ...

  8. RDS for PostgreSQL 云盘加密功能使用方法

    RDS for PostgreSQL支持数据盘的加密功能,提供更高的数据存储安全等级.(加密KEY可以由用户提供,也可以由KMS服务生成.) 使用方法: 1.选中需要购买数据库实例的region,创建 ...

  9. Net基础面试题

    1.c#访问修饰符有哪些,有何异同? private:私有类型,只用当前类可以访问 protected:访问包含类或者类派生的类 internal:程序集类型,在相同的命名空间内可以访问 public ...

  10. PHP与RBAC设计思路讲解与源码

    在说权限管理前,应该先知道权限管理要有哪些功能: (1).用户只能访问,指定的控制器,指定的方法 (2).用户可以存在于多个用户组里 (3).用户组可以选择,指定的控制器,指定的方法 (4).可以添加 ...