题解 CF1684F Diverse Segments
vp 的时候写了一个比较愚蠢的做法过了。
首先选择一个区间修改等价于删掉这个区间。那么考虑它给定的 个区间会有什么影响。假设给定的某个区间是 ,那么假设颜色 在这个区间出现 次,下标是 。那么:
- :没用。
- :答案区间必须要覆盖 ,并且要覆盖 和 的至少一个。
要是得到了所有 ,我们就得到若干个条件形式是下面两者之间一个:
- 必须覆盖 。
- 必须覆盖 和 之一。
很容易贪心去做。具体地,从小到大枚举答案右端点 ,维护一个堆,每次用 减去堆的最小值更新答案。考虑对于第 类条件,我们在左端点的时候加入,到右端点的时候删除左端点,再加入右端点。
但是得到 需要的复杂度还是不对。记在 后且颜色与 相同的第一个位置为 (找不到则为 )。我们考虑把左端点从小到大扫过去,对于位置 ,找到 所在给定区间的最大的 。如果 ,那么 是一定要覆盖的位置(即条件 )。再找到 前面第一个和 同颜色的位置 ,那么需要满足必须覆盖 之一(即条件 )。容易发现这样就涵盖了所有条件。
这样就做完了。实现的时候有点细节。
下面是场上写的丑陋代码,并不建议阅读。有疑问可以私信我。
const int N=500005;
int n,m,sum;
int a[N],s[N],c[N];
int p[N],h[N];
map<int,int>tmp;
int col;
vector<int>b[N];
int g[N];
vector<int>f[N];
void add(int x,int y)
{
sum++;
g[x]++;
f[y].push_back(x);
}
multiset<int>se;
void work()
{
cin >> n >> m;
sum=0;
tmp.clear();
col=0;
for (int i=1;i<=n;i++) cin >> a[i];
for (int i=1;i<=n;i++)
{
g[i]=0;
f[i].clear();
if (tmp[a[i]]==0) tmp[a[i]]=++col;
a[i]=tmp[a[i]];
}
for (int i=1;i<=n;i++) c[i]=0,p[i]=0;
for (int i=n;i>=1;i--)
{
if (p[a[i]]==0) s[i]=n+1;
else s[i]=p[a[i]];
p[a[i]]=i;
}
s[n+1]=n+1;
for (int i=1;i<=n;i++) b[i].clear();
for (int i=1;i<=m;i++)
{
int l,r;
cin >> l >> r;
b[l].push_back(r);
}
for (int i=1;i<=n;i++) b[i].push_back(i);
int mx=0;
for (int i=1;i<=n;i++)
{
for (int j:b[i]) mx=max(mx,j);
int u=s[i],v=s[u];
if (v<=mx) c[u]=1;
}
int l=n+1,r=0;
for (int i=1;i<=n;i++)
{
if (c[i]==1) r=max(r,i),l=min(l,i);
}
for (int i=l;i<=r;i++) c[i]=1;
// cout << l << " " << r << endl << endl;
mx=0;
for (int i=1;i<=n;i++) h[i]=0;
for (int i=1;i<=n;i++)
{
for (int j:b[i])
{
while (mx<j)
{
mx++;
h[a[mx]]=mx;
}
}
if (c[i]) continue;
int u=h[a[i]];
if (i!=u) add(i,u);
}
if (sum==0)
{
if (r==0) cout << 0 << endl;
else cout << r-l+1 << endl;
return;
}
if (r!=0) sum+=r-l+1;
int ans=n,uu=0;
se.clear();
for (int i=1;i<=n;i++)
{
for (int j=1;j<=g[i];j++) se.insert(i),uu++;
if (c[i]) se.insert(i),uu++;
for (int j:f[i])
{
se.erase(se.find(j));
se.insert(i);
}
if (uu==sum) ans=min(ans,i-*se.begin()+1);
//cout << "11c " << *se.begin() << endl;
}
cout << ans << endl;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?