记录编号 192867 评测结果 AAAAAAAAAA
题目名称 [CQOI2011]动态逆序对 最终得分 100
用户昵称 Gravatardevil 是否通过 通过
代码语言 C++ 运行时间 4.569 s
提交时间 2015-10-13 10:42:30 内存使用 2.99 MiB
显示代码纯文本
#include <cstdlib>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <map>
#include <stack>
#include <queue>
#include <ctime>
#include <algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef unsigned int uint;
const int inf=1061109567;
const int maxn=100010;
const int maxm=350;
const int mod=7777777;

ll Read()
{
    ll x=0;char y;int flag=1;
    do{y=getchar();if(y=='-') flag=-1;} while(y<'0'||y>'9');
    do{x=x*10+y-'0';y=getchar();} while(y>='0'&&y<='9');
    return x*flag;
}

int tree[3*maxn],block[maxn];
int a[maxn],p[maxn],b[maxn];
int l[maxm],r[maxm],nl[maxm];
int n,m,s;

int lowbit(int x) {return x&(-x);}

void modify(int x,ll val)
{
    while(x<=n)
    {
        tree[x]+=val;
        x+=lowbit(x);
    }
}

ll getsum(int x)
{
    ll sum=0;
    while(x>0)
    {
        sum+=tree[x];
        x-=lowbit(x);
    }
    return sum;
}

void build_block()
{
    int len=int(sqrt(double(n)));
    if(n%len) s=n/len+1;
    else s=n/len;
    for(int i=1;i<=s;i++)
    {
        l[i]=(i-1)*len+1;r[i]=min(i*len,n);
        sort(b+l[i],b+r[i]+1);nl[i]=l[i];
        for(int j=l[i];j<=r[i];j++) block[j]=i;
    }
}

int found_max(int pos,ll val)
{
    int tl=l[pos],tr=r[pos],m;
    while(tl<=tr)
    {
        m=(tl+tr)/2;
        if(val>b[m]) tl=m+1;
        else tr=m-1;
    }
    return r[pos]-tr;
}

int found_min(int pos,ll val)
{
    int tl=l[pos],tr=r[pos],m;
    while(tl<=tr)
    {
        m=(tl+tr)/2;
        if(val>b[m]) tl=m+1;
        else tr=m-1;
    }
    return tr-nl[pos]+1;
}

ll query(int val)
{
    ll tmp=0;int pos=block[p[val]];
    
    for(int i=1;i<pos;i++) tmp+=found_max(i,val);
    
    for(int i=nl[pos];i<=r[pos];i++)
    {
        if(p[b[i]]<p[val]&&b[i]>val) tmp++;
        if(p[b[i]]>p[val]&&b[i]<val) tmp++;
    }
    
    for(int i=pos+1;i<=s;i++) tmp+=found_min(i,val);
    
    return tmp;
}

void change(int pos)
{
    a[pos]=0;
    for(int i=l[block[pos]];i<=r[block[pos]];i++) b[i]=a[i];
    sort(b+l[block[pos]],b+r[block[pos]]+1);
    nl[block[pos]]++;
}

int main()
{
    freopen("inverse.in","r",stdin);
    freopen("inverse.out","w",stdout);
    //clock_t st=clock();
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        a[i]=Read();
        b[i]=a[i];p[a[i]]=i;
    }
    ll ans=0,t;
    for(int i=1;i<=n;i++)
    {
        modify(a[i],1);
        ans+=i-getsum(a[i]);
    }
    build_block();
    for(int i=1;i<=m;i++)
    {
        printf("%lld\n",ans);
        t=Read();
        ans-=query(t);
        change(p[t]);
    }
    //clock_t ed=clock();
    //printf("\nTime used : %.5lf Ms\n",double(ed-st)/CLOCKS_PER_SEC);
    return 0;
}