题目大意:

\(给你n个数a_i,给定一个m,你可以选择一个区间[l,r],让他们区间加一个任意数,然后询问一次操作完之后,最多能得到多少个m\)

QWQ

考场上真的**

想了好久都不会,直到考试快结束才知道怎么做。

首先,根据题目,我们可以得知,假设我们修改了\([l,r]\)这个区间,那么最后的\(ans\)就应该是总的m的个数,减去区间中m的个数,加上区间内的众数的个数

QWQ

那么我们考虑怎么来处理这个。

首先,每个数字之间都是独立的。

所以我们可以预处理每一个数字出现的位置。

然后假设当前我们要计算的数字是\(x\)

那么,我们可以先对于所有出现的位置\(i\),求一个\([pos_1,pos_i]\)的答案QWQ

转移的式子也是比较显然。

\[dp[i]=di[i-1]+1-(sum_m)
\]

其中\(sum_m\)表示这段区间中的m的个数,这个可以用前缀和来维护

dp[j]=dp[j-1]+1-(sum[v[i][j]]-sum[v[i][j-1]]);

那么既然求出来这个东西,我们考虑左端点每移动一个,相当于对所有的右端点的区间加一个释放出来的贡献,也就是m的个数-1

所以说,我们现在需要一个能支持插入,删除,后缀修改,\(求max\)的一个数据结构

很自然能想到\(multiset\),插入删除和max就不说了,后缀修改的话,我们只需要维护一个\(delta\)表示改变量,对于每个元素,调用的时候都\(+delta\)就解决了

QWQ

给代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#define mk makr_pair
#define ll long long
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while (!isdigit(ch)) {if (ch=='-') f=-1;ch=getchar();}
while (isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
const int maxn = 5e5+1e2;
int n,a[maxn];
int m;
int sum[maxn];
vector<int> v[maxn];
int cnt;
int vis[maxn];
int dp[maxn];
int ans;
int main()
{
n=read(),m=read();
for (int i=1;i<=n;i++) v[i].push_back(0);
for (int i=1;i<=n;i++)
{
a[i]=read();
if (!vis[a[i]])
{
++cnt;
vis[a[i]]=cnt;
}
v[vis[a[i]]].push_back(i);
}
for (int i=1;i<=n;i++) if(a[i]==m) sum[i]=1;
for (int i=1;i<=n;i++) sum[i]+=sum[i-1];
ans=sum[n];
for (int i=1;i<=cnt;i++)
{
if (a[v[i][1]]==m) continue;
int num = v[i].size();
multiset<int> s;
dp[1]=1;
s.insert(1);
for (int j=2;j<num;j++)
{
dp[j]=dp[j-1]+1-(sum[v[i][j]]-sum[v[i][j-1]]);
//cout<<j<<" "<<dp[j]<<endl;
s.insert(dp[j]);
}
ans=max(ans,(*(s.rbegin()))+sum[n]);
int j=1;
int delta=0;
while (j<num-1)
{
s.erase(s.find(dp[j]));
j++;
delta+=sum[v[i][j]]-sum[v[i][j-1]]-1;
ans=max(ans,(*(s.rbegin()))+delta+sum[n]);
}
}
cout<<ans;
return 0;
}

最新文章

  1. PHP源码分析-变量
  2. 利用反射模拟一个spring的内部工作原理
  3. Dojo框架学习笔记&lt;一&gt;
  4. iOS阶段学习第14天笔记(NSString与NSMutableString)
  5. O(nlogn)LIS及LCS算法
  6. Newton-Raphson算法简介及其R实现
  7. IDEA使用的点点滴滴
  8. myGeneration代码生成器
  9. oracle的sql函数
  10. iOS storyBoard中tableViewCell传值方法
  11. visual Studio 无法调试,提示程序跟踪已退出
  12. 第四篇:Web框架 - Django
  13. NSURLRequest的缓存策略
  14. ubuntu 安装 google Gtest [转]有效性待验证
  15. 团队作业M1反思
  16. 【转】Caffe的solver文件配置
  17. python2x 与 python3x 区别
  18. python--使用pickle序列化对象
  19. swift类型擦除的定义-swift的类型擦除只是一个类型高低阶转换的游戏。
  20. Linux中 /boot 目录介绍 【转载】

热门文章

  1. go语言 切片表达式
  2. ES6扩展——数组的新方法(Array.from、Array.of、Array.fill、Array.includes、keys values entries 、find)
  3. Ubuntu16.04 + OpenCV源码 + Qt5.10 安装、配置
  4. JDK和环境配置,eclipse安装与使用
  5. 一、docker部署Jenkins
  6. 简单明了的Java线程池
  7. Python使用openpyxl模块操作Excel表格
  8. Identity角色管理一(准备工作)
  9. 口护万亿市场杀出的实力派 Oclean欧可林
  10. oracle table()函数