Description

给出长度为 \(n\) 序列 \(A_i\),求出所有长度为 \(n\) 的排列 \(P\),满足 \(P_i<=A_i\),求所有满足条件的 \(P\) 的逆序对数之和

题面

Solution

设 \(c[k]\) 表示 \(A_i>=k\) 的个数,那么对于所有的 \(c[k]>=(n-k+1)\),不满足则不合法

把 \(c[k]\) 变为 \(c[k]-(n-k),\)总方案就是 \(\Pi c[k]\)

考虑逆序对 \((i,j)\) 的贡献

如果满足 \(A_i<=A_j\) ,那么把 \(A_j\) 变成 \(A_i\),然后 \((i,j)\) 作为逆序对的方案数就是合法排列的方案数除以 \(2\)

把 \(A_j\) 变成 \(A_i\) 之后,\([A_i+1,A_j]\) 这一个区间的 \(c\) 会减 \(1\),可以维护一个前缀积 \(\frac{c_i-1}{c_i}\) 可以 \(O(1)\) 算出替换后的贡献

那么就可以树状数组维护一下每个数对的贡献了

对于 \(A[i]>A[j]\) 的情况,补集转换一下,总方案-把 \(A_i\) 替换成 \(A_j\) 的方案,然后和上面一样的做一遍就好了

#include<bits/stdc++.h>
using namespace std;
template<class T>void gi(T &x){
int f;char c;
for(f=1,c=getchar();c<'0'||c>'9';c=getchar())if(c=='-')f=-1;
for(x=0;c<='9'&&c>='0';c=getchar())x=x*10+(c&15);x*=f;
} const int N=2e5+10,mod=1e9+7;
inline int qm(int x,int k){
int sum=1;
while(k){
if(k&1)sum=1ll*sum*x%mod;
x=1ll*x*x%mod;k>>=1;
}
return sum;
}
int n,a[N],c[N],v0[N],R[N],tr[N],S;
inline void add(int x,int t){
for(int i=x;i<=n;i+=(i&(-i)))tr[i]=(tr[i]+t)%mod;
}
inline int qry(int x){
int ret=0;
for(int i=x;i>=1;i-=(i&(-i)))ret=(ret+tr[i])%mod;
return ret;
}
int main(){
freopen("pp.in","r",stdin);
freopen("pp.out","w",stdout);
cin>>n;
for(int i=1;i<=n;i++)gi(a[i]),c[a[i]]++;
for(int i=n-1;i>=1;i--)c[i]+=c[i+1]-1;
for(int i=1;i<=n;i++)if(c[i]<=0)return puts("0"),0;
v0[0]=S=1;
for(int i=1;i<=n;i++){
v0[i]=1ll*v0[i-1]*(c[i]>1?c[i]-1:1)%mod*qm(c[i],mod-2)%mod;
S=1ll*S*c[i]%mod;
}
R[n]=n;
for(int i=n-1;i>=1;i--)R[i]=c[i+1]>1?R[i+1]:i;
int ans=0,t;
//A[i]<=A[j]
for(int i=n;i>=1;i--){
t=(qry(R[a[i]])-qry(a[i]-1)+mod)%mod;
ans=(ans+1ll*t*qm(v0[a[i]],mod-2))%mod;
add(a[i],v0[a[i]]);
}
//A[i]>A[j]
R[1]=1;
memset(tr,0,sizeof(tr));
for(int i=2;i<=n;i++)R[i]=c[i]>1?R[i-1]:i;
for(int i=n;i>=1;i--){
t=(qry(a[i]-1)-qry(R[a[i]]-1)+mod)%mod;
ans=(ans-1ll*t*v0[a[i]]%mod+mod)%mod;
add(a[i],qm(v0[a[i]],mod-2));
}
ans=1ll*ans*qm(2,mod-2)%mod;
memset(tr,0,sizeof(tr));
for(int i=1;i<=n;i++){
ans=(1ll*ans+i-1-qry(a[i])+mod)%mod;
add(a[i],1);
}
ans=1ll*ans*S%mod;
cout<<ans<<endl;
return 0;
}

AtCoder Grand Contest 023 E - Inversions的更多相关文章

  1. Atcoder Grand Contest 023 E - Inversions(线段树+扫描线)

    洛谷题面传送门 & Atcoder 题面传送门 毒瘤 jxd 作业-- 首先我们不能直接对所有排列计算贡献对吧,这样复杂度肯定吃不消,因此我们考虑对每两个位置 \(x,y(x<y)\), ...

  2. AtCoder Grand Contest 023 A - Zero-Sum Ranges

    Time limit : 2sec / Memory limit : 256MB Score : 200 points Problem Statement We have an integer seq ...

  3. AtCoder Grand Contest 023 C - Painting Machines

    Description 一个长度为 \(n\) 的序列,初始都为 \(0\),你需要求出一个长度为 \(n-1\) 的排列 \(P\), 按照 \(1\) 到 \(n\) 的顺序,每次把 \(P_i\ ...

  4. AtCoder Grand Contest 023 F - 01 on Tree

    Description 题面 Solution HNOI-day2-t2 复制上去,删点东西,即可 \(AC\) #include<bits/stdc++.h> using namespa ...

  5. Atcoder Grand Contest 023

    A 略 B 略 C(计数) 题意: 有n个白球排成一行,故有n-1个空隙,我可以给一个空隙对应的两个白球都涂黑.n-1个空隙的一个排列就对应着一个涂黑顺序,定义这个涂黑顺序的价值是“将所有n个球都涂黑 ...

  6. AtCoder Grand Contest 012

    AtCoder Grand Contest 012 A - AtCoder Group Contest 翻译 有\(3n\)个人,每一个人有一个强大值(看我的假翻译),每三个人可以分成一组,一组的强大 ...

  7. AtCoder Grand Contest 011

    AtCoder Grand Contest 011 upd:这篇咕了好久,前面几题是三周以前写的... AtCoder Grand Contest 011 A - Airport Bus 翻译 有\( ...

  8. AtCoder Grand Contest 031 简要题解

    AtCoder Grand Contest 031 Atcoder A - Colorful Subsequence description 求\(s\)中本质不同子序列的个数模\(10^9+7\). ...

  9. AtCoder Grand Contest 010

    AtCoder Grand Contest 010 A - Addition 翻译 黑板上写了\(n\)个正整数,每次会擦去两个奇偶性相同的数,然后把他们的和写会到黑板上,问最终能否只剩下一个数. 题 ...

随机推荐

  1. 【题解】 UVa11300 Spreading the Wealth

    题目大意 圆桌旁边坐着\(n\)个人,每个人有一定数量的金币,金币的总数能被\(n\)整除.每个人可以给他左右相邻的人一些金币,最终使得每个人的金币数量相等.您的任务是求出被转手的金币的数量的最小值. ...

  2. Kotlin if else判断

    Kotlin的if相对与java,有着较为灵活的用法. if是用来判断. if在Kotlin里面可以作为表达式来使用. 如果熟悉C java C#等 A>B:A?B这个判断应该是很熟悉,而Kot ...

  3. ASPxGridView编辑时弹出的editform值不是当前行值的原因

    如下图所示(左边是红框是ASPxGridView编辑的行,右边是弹出的editform上显示的值). 这是因为ASPxGridView的KeyFieldName的值不是唯一的,需要修改或增加条件使键值 ...

  4. 【Jquery】jquery刷新页面(局部及全页面刷新)

    下面介绍全页面刷新方法:有时候可能会用到window.location.reload()刷新当前页面.parent.location.reload()刷新父亲对象(用于框架)opener.locati ...

  5. 使用C#来编写一个异步的Socket服务器

    介绍 我最近需要为一个.net项目准备一个内部线程通信机制. 项目有多个使用ASP.NET,Windows 表单和控制台应用程序的服务器和客户端构成. 考虑到实现的可能性,我下定决心要使用原生的soc ...

  6. js事件处理程序return false ,preventDefault,returnValue

    面试题目中,经常会被问到如何阻止默认行为. 以下是<javascript权威指南>书中的内容,详情可以去看书. 能够取消事件默认操作的方法有三种 1.属性注册的事件处理程序的返回值fals ...

  7. Android StateListDrawable资源的使用(文本的高亮显示)

    1.介绍 2.xml文件属性介绍 3.实例演示 <1>新建drawable文件 app--->src---->main---->res---->drawable , ...

  8. ui-grid 中cellTemplate中click事件

    cellTemplate中使用的函数: 外部定义的函数:

  9. HDU 6356 (线段树-l,r 之间小于val 的变val+单点求值)

    题目描述: 给你一个长度为n的最开始为0的数以及m个更新操作以及数据生成器参数X,Y,Z.每次操作,将由数据生成器生成出li,ri,vi.让你从区间[li,ri]中,将所有小于vi的数变为vi.最后让 ...

  10. ACM浮点数相关的陷阱

    误差修正 因为被计算机表示浮点数的方式所限制,CPU在进行浮点数计算时会出现误差.如执行0.1 + 0.2 == 0.3结果往往为false,在四则运算中,加减法对精度的影响较小,而乘法对精度的影响更 ...