原题链接:http://codeforces.com/contest/788/problem/E
题解:
先离散化,然后通过两个树状数组处理出ai<=aj (i<j)的对数,和ai>=aj (i<j) 的对数,然后,对于每一种数字建立一颗线段树,其中线段树维护六个值为:
L:这个区间中,ai<=aj (i<j)的对数。
R:这个区间中,ai>=aj (i<j) 的对数。
M:这个节点中数的个数。
LM:这个区间中,三元组满足 ai<=aj ==ap(i<j<p) 的组数。
RM:这个区间中,三元组满足 ai==aj>=ap (i<j<p) 的组数。
LMR:这个区间中,五元组满足 ai<=aj==ak==ap>=aq (i<j<k<p<q) 的组数
对于更新操作,每次只更新一条链即可,其中
L=(lson->L+rson->L);
M=(lson->M+rson->M);
R=(lson->R+rson->R);
LM=(lson->LM+rson->LM+lson->L*rson->M);
MR=(lson->MR+rson->MR+lson->M*rson->R);
LMR=(lson->LMR+rson->LMR+lson->LM*rson->R+lson->L*rson->MR);
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN=1e5+5;
const int MOD=1e9+7;
int al[MAXN],ar[MAXN],a[MAXN];
int Hash[MAXN];
int id[MAXN],num[MAXN],pos[MAXN];
int cnt=1;
struct node
{
int l,r;
node *lson,*rson;
ll L,M,R,LM,MR,LMR;
node(int _l,int _r):l(_l),r(_r)
{
if(l==r)
{
return ;
}
int m=(l+r)>>1;
lson=new node(l,m);
rson=new node(m+1,r);
}
void update(int k,int l,int r,int ID)
{
if(l==r)
{
L=pos[ID]*al[ID];
M=pos[ID];
R=pos[ID]*ar[ID];
LM=MR=LMR=0;
//printf("%lld %lld %lld\n",L,M,R);
return ;
}
int m=(l+r)>>1;
if(k<=m)
lson->update(k,l,m,ID);
if(k>m)
rson->update(k,m+1,r,ID);
L=(lson->L+rson->L)%MOD;
M=(lson->M+rson->M)%MOD;
R=(lson->R+rson->R)%MOD;
LM=(lson->LM+rson->LM+lson->L*rson->M)%MOD;
MR=(lson->MR+rson->MR+lson->M*rson->R)%MOD;
LMR=(lson->LMR+rson->LMR+lson->LM*rson->R+lson->L*rson->MR)%MOD;
}
}*sv[MAXN];
struct bit
{
int n;
ll a[MAXN];
void init(int _n)
{
memset(a,0,sizeof(a));
n=_n;
}
int lowbit(int x)
{
return x&(-x);
}
void update(int x,int add)
{
while(x<=n)
{
a[x]+=add;
x+=lowbit(x);
}
}
ll query(int x)
{
ll ret=0;
while(x)
{
ret+=a[x];
ret%=MOD;
x-=lowbit(x);
}
return ret;
}
}LT,RT;
int getid(int x)
{
int ret=lower_bound(Hash+1,Hash+cnt+1,x)-Hash;
return ret;
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n;
scanf("%d",&n);
LT.init(n),RT.init(n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
Hash[cnt++]=a[i];
pos[i]=1;
}
sort(Hash+1,Hash+cnt);
cnt=unique(Hash+1,Hash+cnt)-Hash-1;
for(int i=1;i<=n;i++)
{
a[i]=getid(a[i]);
id[i]=++num[a[i]];
}
for(int i=1;i<=n;i++)
{
al[i]=LT.query(a[i]);
LT.update(a[i],1);
}
for(int i=n;i>=1;i--)
{
ar[i]=RT.query(a[i]);
RT.update(a[i],1);
}
for(int i=1;i<=cnt;i++)
{
sv[i]=new node(1,num[i]);
}
for(int i=1;i<=n;i++)
{
sv[a[i]]->update(id[i],1,num[a[i]],i);
}
ll ans=0;
for(int i=1;i<=cnt;i++)
{
ans+=sv[i]->LMR;
ans%=MOD;
}
int m;
scanf("%d",&m);
while(m--)
{
int q,at;
scanf("%d%d",&q,&at);
ans=(ans-sv[a[at]]->LMR+MOD)%MOD;
pos[at]^=1;
sv[a[at]]->update(id[at],1,num[a[at]],at);
ans=(ans+sv[a[at]]->LMR)%MOD;
printf("%lld\n",ans);
}
return 0;
}