CF1637H
分析贡献,子序列内部贡献和对外面的贡献分开算。
取下标为 的子序列,设 ,
则外部贡献为 。
内部贡献为 。
上面都是我能做的
然后出现了性质:对于原序列中的逆序对 ,只选 是比只选 不劣的。
证明见:https://www.cnblogs.com/PinkRabbit/p/CF1637.html
大概是反正,取距离最近一组不合法数对,分析贡献。
那么最终选得的每一个数,其后的所有逆序对都必选。
因此 。
因此一个数的贡献就是 。
排序后贪心取前 个。
结论的作用应该是把贡献具体到每个数上了。
#include<bits/stdc++.h>
#define fo(i,a,b) for(int i=a;i<=b;++i)
#define fd(i,a,b) for(int i=a;i>=b;--i)
using namespace std;
typedef long long ll;
const int N=5e5+10;
int T,n,a[N],c[N],tr[N];
inline int query(int x){int ret=0; for(;x;x&=(x-1))ret+=tr[x]; return ret;}
inline void add(int x,int v){for(;x<=n;x+=(x&(-x)))tr[x]+=v;}
int main(){
freopen("data.in","r",stdin);
freopen("data.out","w",stdout);
scanf("%d",&T);
while(T--){
scanf("%d",&n);
fo(i,1,n)scanf("%d",&a[i]),tr[i]=c[i]=0;
ll sum=0;
fd(i,n,1){
int v=query(a[i]);
sum+=v;
c[i]=(n-a[i])-(n-i-v);
c[i]-=2*v+(a[i]-1-v);
add(a[i],1);
}
sort(c+1,c+n+1,greater<int>());
ll s=0;
printf("%lld ",sum);
fo(i,1,n){
s+=c[i];
printf("%lld ",sum-s-(ll)i*(i-1)/2);
}
printf("\n");
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话