P1667 数列
区间操作的维护看起来很麻烦,考虑转为点操作的维护。题目中的
接下来我们考虑
然后就发现这其实就是交换操作。
接下来考虑,我们的目标是使得序列
所以,我们的问题转化为了:每次操作可选择一对
那这就是个经典问题了,可以用找置换环的方式解决,具体来说,我们记 cnt++
。
最终答案就是
最后的最后,我们来考虑判断无解情况,首先如果
以上这些判断可以合并成:
sort(s+1,s+n);
for(re int i=1;i<=n;i++)
if(s[i]<=s[i-1]){
puts("-1");
return 0;
}
然后这题就做完了。
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define il inline
#define re register
const int N=100100;
int n,a[N],s[N],b[N],mx=-1e18;
unordered_map<int,int>mp;
bitset<N>vis;
il int read(){
re int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar();
return x*f;
}
signed main(){
n=read();
for(re int i=1;i<=n;i++)
a[i]=read(),b[i]=s[i]=s[i-1]+a[i];
sort(s+1,s+n);
for(re int i=1;i<=n;i++)
if(s[i]<=s[i-1]){
puts("-1");
return 0;
}
for(re int i=1;i<n;i++)mp[s[i]]=i;
int cnt=0;
for(re int i=1;i<n;i++){
if(vis[i])continue;
int j=i;
while(!vis[j]){
vis[j]=1;
j=mp[b[j]];
}
cnt++;
}
cout<<n-1-cnt;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)