AtCoder Grand Contest 023
链接
D. Go Home
考虑两端的最后一组到的人,如果左边的人数大于等于右边,那么右边的人只能希望左边的人快点到,所以他们会和左边的人投一样的票。然后就可以把这组人加到左边去,这样就变成了一个子问题。
最后全部在公司一侧了就直接开过去即可。复杂度 。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 100010
#define ll long long
using namespace std;
int x[N],n,s;
ll p[N];
int main()
{
scanf("%d%d",&n,&s);
for(int i=1;i<=n;i++) scanf("%d%lld",&x[i],&p[i]);
int l=1,r=n,op=p[1]>=p[n];
ll ans=0;
while(l<=r)
{
if(x[l]>s){ans+=x[r]-s;break;}
if(x[r]<s){ans+=s-x[l];break;}
if(p[l]>=p[r]) p[l]+=p[r],ans+=op*(x[r]-x[l]),op=0,r--;
else p[r]+=p[l],ans+=(1-op)*(x[r]-x[l]),op=1,l++;
}
printf("%lld\n",ans);
return 0;
}
E. Inversions
首先考虑 怎么做:
考虑算原序列的一种方法:用 表示 的数量,那么 可以放在这 个位置上,但其中恰好有 个位置已经放了数字,所以总共还剩 个位置。令 。
然后考虑将逆序对分开处理贡献,即考虑 的方案数。
不妨钦定此时 ,那么要产生逆序对当且仅当 位置的值比 小,可以发现这部分等价于 ,即逆序对数等于总数除以二。但同时所有位于 中的数字都会少 的答案,所以总方案数就是 。
对于 的情况,可以发现就是总方案减去上述方案。
直接枚举 就是 。考虑优化。
可以发现枚举 ,总方案数本质上是一些后缀积的和,所以直接用树状数组维护即可。复杂度 。
注意特判 0。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=200010,mod=1000000007,iv2=(mod+1)/2;
int n;
int ksm(int a,int b=mod-2)
{
int r=1;
for(;b;b>>=1,a=1ll*a*a%mod) if(b&1) r=1ll*r*a%mod;
return r;
}
struct tree_a{
int a[N];
void clear(){memset(a,0,sizeof(a));}
void add(int x,int v){for(;x<=n;x+=(x&-x)) a[x]=(a[x]+v)%mod;}
int qry(int x){int v=0;for(;x;x-=(x&-x)) v=(v+a[x])%mod;return v;}
int sum(int l,int r){return (qry(r)-qry(l-1)+mod)%mod;}
}c0,c1;
int a[N],p[N],M=1;
int pre[N],sum[N];
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]),p[a[i]]++;
for(int i=n-1;i;i--) p[i]+=p[i+1];
for(int i=1;i<=n;i++) p[i]-=n-i,M=1ll*M*p[i]%mod;
sum[0]=pre[0]=1;
for(int i=1;i<=n;i++)
{
if(p[i]<=1) pre[i]=i,sum[i]=sum[i-1];
else pre[i]=pre[i-1],sum[i]=1ll*sum[i-1]*(p[i]-1)%mod*ksm(p[i])%mod;
}
int ans=0;
for(int i=1;i<=n;i++)
{
ans=(ans+1ll*c0.sum(pre[a[i]],a[i])*sum[a[i]]%mod*iv2%mod)%mod;
c0.add(a[i],ksm(sum[a[i]]));
}
c0.clear();
for(int i=n;i;i--)
{
ans=(ans+c1.qry(a[i]-1)-1ll*c0.sum(pre[a[i]],a[i]-1)*sum[a[i]]%mod*iv2%mod+mod)%mod;
c0.add(a[i],ksm(sum[a[i]]));c1.add(a[i],1);
}
ans=1ll*ans*M%mod;
printf("%d\n",ans);
return 0;
}
F. 01 on Tree
题解
本文来自博客园,作者:Flying2018,转载请注明原文链接:https://www.cnblogs.com/Flying2018/p/agc023.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理