CF1082E Increasing Frequency (multiset+乱搞+贪心)
2024-10-19 12:34:04
题目大意:
\(给你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;
}
最新文章
- PHP源码分析-变量
- 利用反射模拟一个spring的内部工作原理
- Dojo框架学习笔记<;一>;
- iOS阶段学习第14天笔记(NSString与NSMutableString)
- O(nlogn)LIS及LCS算法
- Newton-Raphson算法简介及其R实现
- IDEA使用的点点滴滴
- myGeneration代码生成器
- oracle的sql函数
- iOS storyBoard中tableViewCell传值方法
- visual Studio 无法调试,提示程序跟踪已退出
- 第四篇:Web框架 - Django
- NSURLRequest的缓存策略
- ubuntu 安装 google Gtest [转]有效性待验证
- 团队作业M1反思
- 【转】Caffe的solver文件配置
- python2x 与 python3x 区别
- python--使用pickle序列化对象
- swift类型擦除的定义-swift的类型擦除只是一个类型高低阶转换的游戏。
- Linux中 /boot 目录介绍 【转载】
热门文章
- go语言 切片表达式
- ES6扩展——数组的新方法(Array.from、Array.of、Array.fill、Array.includes、keys values entries 、find)
- Ubuntu16.04 + OpenCV源码 + Qt5.10 安装、配置
- JDK和环境配置,eclipse安装与使用
- 一、docker部署Jenkins
- 简单明了的Java线程池
- Python使用openpyxl模块操作Excel表格
- Identity角色管理一(准备工作)
- 口护万亿市场杀出的实力派 Oclean欧可林
- oracle table()函数