1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
| #include "emhash.h"
#include<cstdio> #include<vector> #include<cstring> #include<algorithm> #include<unordered_map> using namespace std; using ll=long long; constexpr int N=100010,B=700,LB=10,FSIZE=1<<16; int n,k,q,a[N],b[N],pre[N],num[N],big; ll ans,to[N/B][N]; vector<int> v[N];
emhash7::HashMap<ll,ll> old; struct FT{ int a[N]; void modify(int x){for(;x;x-=x&-x) ++a[x];} void query(int x){for(;x<=n;x+=x&-x) ans+=a[x];} }ini; char BuF[FSIZE],*InF=BuF,WuF[FSIZE],*OnF=WuF,ST[20],*STC=ST; inline char nxtc(){ if(BuF+FSIZE==InF) fread(InF=BuF,1,FSIZE,stdin); return(*InF++); } inline void putc(char c){ if(WuF+FSIZE==OnF) fwrite(OnF=WuF,1,FSIZE,stdout); *OnF++=c; } template<typename T>inline void read(T &x){ char c=nxtc(); while(c<33) c=nxtc(); for(x=0;32<c;c=nxtc()) x=x*10+(c^48); } void write(ll x){ if(!x) putc(48); for(;x;x/=10) *++STC=x%10^48; for(;STC!=ST;putc(*STC--)); putc('\n'); } void calc(int num,int is){ for(int i:v[is]) to[num][is]+=pre[i]; } int main(){ fread(BuF,1,FSIZE,stdin); read(n);read(k);read(q); for(int i=1;i<=n;++i){ read(a[i]); ini.query(a[i]+1); ini.modify(a[i]); v[a[i]].push_back(i); } for(int i=1;i<=k;++i){ int s=v[i].size(); if(s>B){ num[i]=++big; for(int j=1,k=0;j<=n;++j){ for(;k<s&&v[i][k]<j;++k); pre[j]=k; } for(int j=1;j<i;++j) calc(big,j); for(int j=n;j>i;--j) calc(big,j); } } for(int i=1;i<=n;++i) b[i]=i; for(int p;q--;){ read(p); int x=b[p],y=b[p+1],sx=v[x].size(),sy=v[y].size(); auto add=[&](ll s){ if(x==b[p]) ans+=s+s-(ll)sx*sy; else ans+=(ll)sx*sy-s-s; }; if(sx<sy){ swap(x,y); swap(sx,sy); } if(sx<=B){ ll tmp=x*n+y; auto p=old.insert(make_pair(tmp,0)); ll &sum=p.first->second; if(p.second) for(int i=0,j=0;j<sy;++j){ for(;i<sx&&v[x][i]<v[y][j];++i); sum+=i; } add(sum); }else add(to[num[x]][y]); swap(b[p],b[p+1]); write(ans); } fwrite(WuF,1,OnF-WuF,stdout); return(0); }
|