Codechef:Sereja and Arcs(SEAARC)
阿新 • • 發佈:2018-12-14
題解: 這種題顯然對出現次數分類討論一下。
出現少的做,出現多的做,最後可以做到的複雜度。
#include <bits/stdc++.h>
using namespace std;
typedef pair <int,int> pii;
const int RLEN=1<<18|1;
inline char nc() {
static char ibuf[RLEN],*ib,*ob;
(ib==ob) && (ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
return (ib==ob) ? -1 : *ib++;
}
inline int rd() {
char ch=nc(); int i=0,f=1;
while(!isdigit(ch)) {if(ch=='-')f=-1; ch=nc();}
while(isdigit(ch)) {i=(i<<1)+(i<<3)+ch-'0'; ch=nc();}
return i*f;
}
const int N=1e5+50, L=1e5, mod=1e9+7, S=80, inv=(mod+ 1)/2;
inline int add(int x,int y) {return (x+y>=mod) ? (x+y-mod) : (x+y);}
inline int dec(int x,int y) {return (x-y<0) ? (x-y+mod) : (x-y);}
inline int mul(int x,int y) {return (long long)x*y%mod;}
inline void up(int &x,int y) {x=add(x,y);}
inline void dn(int &x,int y) {x=dec(x,y);}
int n,a[N],l[N],r[N],c[N],last[N];
inline int calc_AABB() {
static int cnt[N],s[N],s2[N],sum,ans;
for(int i=1;i<=n;i++) {
up(ans,s[a[i]]);
up(s[a[i]],dec(sum,s2[a[i]]));
up(sum,cnt[a[i]]);
up(s2[a[i]],cnt[a[i]]);
up(cnt[a[i]],1);
} return ans;
}
inline int calc_ABBA(int x) {
static int tot,suf[N],ans; tot=0,ans=0;
static int cnt[N],s[N],s2[N];
for(int i=1;i<=n;i++) cnt[a[i]]=s[a[i]]=s2[a[i]]=0;
for(int i=n;i>=1;i--) {
suf[i]=add(suf[i+1],a[i]==x);
tot+=(a[i]==x);
}
for(int i=1;i<=n;i++) {
if(a[i]!=x) {
up(ans,mul(cnt[a[i]],mul(suf[i],tot)));
dn(ans,mul(s[a[i]],suf[i]));
up(s[a[i]],suf[i]);
up(cnt[a[i]],1);
}
}
for(int i=1;i<=n;i++) cnt[a[i]]=s[a[i]]=0;
for(int i=1;i<=n;i++)
if(a[i]!=x && c[a[i]]<=S) {
int res=0;
up(res,s2[a[i]]);
dn(res,mul(2,mul(suf[i],s[a[i]])));
dn(res,s[a[i]]);
int aa=mul(suf[i],suf[i]);
up(res,mul(cnt[a[i]],aa));
up(res,mul(cnt[a[i]],suf[i]));
up(s2[a[i]],aa);
up(cnt[a[i]],1);
up(s[a[i]],suf[i]);
up(ans,mul(res,inv));
}
return ans;
}
int bit[N];
inline void inc(int i,int v) {for(;i;i-=i&(-i)) bit[i]+=v;}
inline int ask(int i,int v=0) {for(;i<=n;i+=i&(-i)) v+=bit[i]; return v;}
inline int solve() {
int ans=0;
for(int i=1;i<=n;i++) if(c[a[i]]<=S) {
for(int j=r[i];j;j=r[j]) up(ans,ask(j+1));
for(int j=r[i];j;j=r[j]) inc(j,1);
}
memset(bit,0,sizeof(bit));
for(int i=1;i<=L;i++) if(c[i]<=S && last[i]) {
vector <int> vec;
for(int j=last[i];j;j=r[j]) vec.push_back(j);
for(int j=0;j<vec.size();++j) {
for(int k=j+1;k<vec.size();++k) dn(ans,ask(vec[k]+1));
for(int k=j+1;k<vec.size();++k) inc(vec[k],1);
}
for(int j=0;j<vec.size();++j)
for(int k=j+1;k<vec.size();++k) inc(vec[k],-1);
} return ans;
}
int main() {
n=rd();
for(int i=1;i<=n;i++) ++c[a[i]=rd()];
for(int i=n;i;i--) {
r[i]=last[a[i]];
last[a[i]]=i;
}
int ans=0, cnt=0;
for(int i=1;i<=L;i++) if(c[i]) {
int res=(long long)c[i]*(c[i]-1)/2%mod;
up(ans,mul(cnt,res)); up(cnt,res);
}
dn(ans,calc_AABB());
for(int i=1;i<=L;i++) if(c[i]>S) dn(ans,calc_ABBA(i));
dn(ans,solve());
cout<<ans<<'\n';
}