NOIP一模DAY 1爆炸记
由于本蒟蒻太弱了,再加上刚开学心态没调整好,day 1直接炸穿,模拟都没写出来qwq。
在此只是更新一下题解
T1 自己找个骰子模拟;
T2 很显然我们要枚举数列每个元素i,求1到i-1、i+1到n 中比它大的数的个数和比它小的数的个数,朴素的方法是N^2的,我们需要优化,我们可以先离散化,建一课1到n的树状数组(代表某个值域中出现了几个数),每次枚举一个点时,log n查询,查询完后单点修改,复杂度nlogn;
#include<iostream>
#include<cstdio>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=200006;
const long long mod=1e9+7;
int n;
int c[maxn*2];
inline void update (int wh,int x)
{
for (int i=wh;i<=n;i+=(i&-i)) c[i]+=x;
}
inline int query (int wh)
{
int ans=0;
for (int i=wh;i>0;i-=(i&-i))
{
ans+=c[i];
}
return ans;
}
long long litt1[maxn],litt2[maxn],big1[maxn],big2[maxn];
struct hzw
{
int v;
int rv;
int id;
}t[maxn];
bool cmp(hzw a,hzw b)
{
return a.rv<b.rv;
}
bool cmp2(hzw a,hzw b)
{
return a.id<b.id;
}
int main()
{
freopen("sub.in","r",stdin);
freopen("sub.out","w",stdout);
cin>>n;
for (int i=1;i<=n;++i)
{
scanf("%d",&t[i].rv);
t[i].id=i;
}
sort(t+1,t+1+n,cmp);
int tot=0;
for (int i=1;i<=n;++i)
{
if (t[i].rv!=t[i-1].rv)
{
t[i].v=++tot;
}
else t[i].v=t[i-1].v;
}
sort(t+1,t+1+n,cmp2);
for (int i=1;i<=n;++i)
{
litt1[i]=query(t[i].v-1);
big1[i]=query(n)-query(t[i].v);
update(t[i].v,1);
}
memset(c,0,sizeof(c));
for (int i=n;i>=1;i--)
{
litt2[i]=query(t[i].v-1);
big2[i]=query(n)-query(t[i].v);
update(t[i].v,1);
}
long long ans=0;
for (int i=1;i<=n;++i)
{
ans=(ans+(big1[i]*litt2[i])%mod+(big2[i]*litt1[i])%mod)%mod;
}
cout<<ans;
return 0;
}