bzoj3295【CDQ分治】

来源:互联网 发布:备孕前准备 知乎 编辑:程序博客网 时间:2024/06/07 00:27

答案在long long 范围内

#include<iostream>#include<algorithm>#include<cstdio>#include<cstdlib>#include<cstring>using namespace std;typedef long long LL;inline int read(){    int x=0;bool f=0;char c=getchar();    for (;c<'0'||c>'9';c=getchar()) f=c=='-'?1:0;    for (;c>='0'&&c<='9';c=getchar()) x=x*10+c-'0';    return f?-x:x;}const int N=100010,M=50010;int n,m,A[N],pos[N],add[N],ans[N],ss[N];LL ans0=0;struct na{    int x,y,t,id;}e[N+M],e1[N+M],e2[N+M];inline bool cmp(const na &a,const na &b){    if (a.y!=b.y) return a.y<b.y;    return a.t<b.t;} inline void add1(int x,int a)//维护前缀和{    for (;x<=n;x+=x&-x) ss[x]+=a;}inline int cal1(int x){    int rec=0;    for (;x;x-=x&-x) rec+=ss[x];    return rec;} inline void add2(int x,int a)//维护后缀和{    for (;x;x-=x&-x) ss[x]+=a;}inline int cal2(int x){    int rec=0;    for (;x<=n;x+=x&-x) rec+=ss[x];    return rec;}  void solve(int hd,int tl,int l,int r){    if (hd>=tl||l>=r) return;    int mid=l+r>>1;    for (int i=hd;i<=tl;i++)    {        if (e[i].t<=mid&&!e[i].id) add2(e[i].x,1);        if (e[i].t>mid&&e[i].id) ans[e[i].id]+=cal2(e[i].x+1);    }    for (int i=hd;i<=tl;i++)        if (e[i].t<=mid&&!e[i].id) add2(e[i].x,-1);    for (int i=tl;i>=hd;i--)    {        if (e[i].t<=mid&&!e[i].id) add1(e[i].x,1);        if (e[i].t>mid&&e[i].id) ans[e[i].id]+=cal1(e[i].x-1);    }    for (int i=tl;i>=hd;i--)        if (e[i].t<=mid&&!e[i].id) add1(e[i].x,-1);    int l1=0,l2=0,lp=hd;    for (int i=hd;i<=tl;i++)        if (e[i].t<=mid) e1[++l1]=e[i];            else e2[++l2]=e[i];    for (int i=1;i<=l1;i++) e[lp++]=e1[i];    for (int i=1;i<=l2;i++) e[lp++]=e2[i];    solve(hd,hd+l1-1,l,mid);    solve(hd+l1,tl,mid+1,r);}  int main(){    n=read();m=read();    for (int i=1;i<=n;i++) pos[A[i]=read()]=i;    for (int i=n;i;i--) ans0+=cal1(A[i]-1),add1(A[i],1);    memset(ss,0,sizeof ss);    for (int i=1;i<=m;i++)    {        e[i].y=read();e[i].x=pos[e[i].y];        e[i].id=i;add[e[i].x]=e[i].t=m+1-i;    }    for (int i=1;i<=n;i++)     {        if (!add[i]) add[i]=1;        e[i+m].x=i;e[i+m].y=A[i];e[i+m].t=add[i];    }    sort(e+1,e+n+m+1,cmp);    solve(1,n+m,1,m);    for (int i=1;i<=m;i++) printf("%lld\n",ans0),ans0-=ans[i];    return 0;}


0 0
原创粉丝点击