树状数组套线段树,用动态开点线段树。此类就这一题放在这吧。
程序写的太丑了,不要介意。
#include<iostream> #include<cstdio> using namespace std; typedef long long i64; const int N=1e5+5; const int S=1e7+7; int a[N],p[N]; int q[N]; bool b[N]; int r[N]; int cnt,x[S],c[S][2]; i64 ans[N]; void add(int &v,int xx,int l,int r){ if(!v) v=++cnt; ++x[v]; if(l==r) return; int mid=(l+r)>>1; if(xx<=mid) add(c[v][0],xx,l,mid); else add(c[v][1],xx,mid+1,r); } int ct(int &v,int xx,int yy,int l,int r){ if(!v) return 0; if(xx<=l&&r<=yy) return x[v]; int mid=(l+r)>>1,s=0; if(xx<=mid) s+=ct(c[v][0],xx,yy,l,mid); if(mid<yy) s+=ct(c[v][1],xx,yy,mid+1,r); return s; } int n; void ins(int p,int a){ int i; for(i=p;i<=n;i+=-i&i) add(r[i],a,1,n); } int clc(int p,int a){ int i,s=0; for(i=p;i;i-=-i&i) s+=ct(r[i],a+1,n,1,n); for(i=n;i;i-=-i&i) s+=ct(r[i],1,a-1,1,n); for(i=p;i;i-=-i&i) s-=ct(r[i],1,a-1,1,n); return s; } int main() { int m,i; i64 s=0; scanf("%d%d",&n,&m); for(i=1;i<=n;i++){ scanf("%d",&a[i]); p[a[i]]=i; } for(i=1;i<=m;i++){ scanf("%d",&q[i]); b[p[q[i]]]=1; } for(i=1;i<=n;i++) if(!b[i]){ s+=clc(i,a[i]); ins(i,a[i]); } for(i=m;i;i--){ s+=clc(p[q[i]],q[i]); ins(p[q[i]],q[i]); ans[i]=s; } for(i=1;i<=m;i++) printf("%lld\n",ans[i]); return 0; }
用cdq分治更好。
#include<iostream> #include<cstdio> using namespace std; typedef long long i64; const int N=1e5+5; i64 ans[N]; struct inf{ int p,t; i64 *q; }x[N],y[N]; int n; int bt[N],mt[N]; int a[N],q[N]; void add(int t){ for(;t<=n;t+=t&-t) ++bt[t]; } void dec(int t){ for(;t<=n;t+=t&-t) --bt[t]; } int ask(int t){ int s=0; for(;t;t-=t&-t) s+=bt[t]; return s; } void _add(int t){ for(;t<=n;t+=t&-t) ++mt[t]; } void _dec(int t){ for(;t<=n;t+=t&-t) --mt[t]; } int _ask(int t){ int s=0; for(;t;t-=t&-t) s+=mt[t]; return s; } void cdqdc(int l,int r){ if(l==r) return; int mid=(l+r)>>1; cdqdc(l,mid); cdqdc(mid+1,r); int i,j,p; for(i=l;i<=mid;i++) _add(x[i].t); for(i=l,j=mid+1,p=l;i<=mid||j<=r;p++) if(j>r||i<=mid&&x[i].p<x[j].p){ *x[i].q+=ask(x[i].t); _dec(x[i].t); y[p]=x[i++]; } else{ add(x[j].t); *x[j].q+=_ask(x[j].t); y[p]=x[j++]; } for(j=mid+1;j<=r;j++) dec(x[j].t); for(p=l;p<=r;p++) x[p]=y[p]; } int main() { int m,i; scanf("%d%d",&n,&m); for(i=1;i<=n;i++){ scanf("%d",&a[i]); x[a[i]].p=i; x[a[i]].q=ans+m+1; } for(i=1;i<=m;i++){ scanf("%d",&q[i]); x[q[i]].t=n-i+1; x[q[i]].q=ans+i; } int s=0; for(i=1;i<=n;i++) if(!x[i].t) x[i].t=++s; cdqdc(1,n); for(i=m;i;i--) ans[i]+=ans[i+1]; for(i=1;i<=m;i++) printf("%lld\n",ans[i]); return 0; }
原文地址:https://www.cnblogs.com/wanghaoyu/p/Solution2.html
时间: 2024-09-30 11:43:15