[BZOJ3289]Mato的文件管理
思路:
莫队。首先将数据离散化,然后一边莫队一边树状数组求逆序对。
1 #include<cmath> 2 #include<cstdio> 3 #include<cctype> 4 #include<cstring> 5 #include<algorithm> 6 inline int getint() { 7 char ch; 8 while(!isdigit(ch=getchar())); 9 int x=ch^'0'; 10 while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0'); 11 return x; 12 } 13 struct num { 14 int v,id,rank; 15 bool operator < (const num &x) const { 16 return v<x.v; 17 } 18 }; 19 bool cmp(num a,num b) { 20 return a.id<b.id; 21 } 22 int n,r=0; 23 const int N=50001; 24 class FenwickTree { 25 private: 26 int val[N]; 27 int lowbit(const int x) { 28 return x&-x; 29 } 30 public: 31 FenwickTree() { 32 memset(val,0,sizeof val); 33 } 34 void modify(int p,const int x) { 35 while(p<=r) { 36 val[p]+=x; 37 p+=lowbit(p); 38 } 39 } 40 int query(int p) { 41 int ans=0; 42 while(p) { 43 ans+=val[p]; 44 p-=lowbit(p); 45 } 46 return ans; 47 } 48 }; 49 int base; 50 struct Que { 51 int l,r,id; 52 bool operator < (const Que &x) const { 53 return ((l-1)/base<(x.l-1)/base)?true:(((l-1)/base==(x.l-1)/base)?(r<x.r):false); 54 } 55 }; 56 FenwickTree t; 57 int main() { 58 n=getint(); 59 num a[n+1]; 60 a[0]=(num){0,0,0}; 61 for(int i=1;i<=n;i++) a[i]=(num){getint(),i,0}; 62 std::sort(&a[1],&a[n+1]); 63 for(int i=1;i<=n;i++) a[i].rank=(a[i].v==a[i-1].v)?r:++r; 64 std::sort(&a[1],&a[n+1],cmp); 65 base=(int)sqrt(n); 66 int m=getint(); 67 Que q[m]; 68 for(int i=0;i<m;i++) { 69 q[i].l=getint(),q[i].r=getint(); 70 q[i].id=i; 71 } 72 std::sort(&q[0],&q[m]); 73 int ans[m]; 74 for(int i=0,l=1,r=0,Ans=0;i<m;i++) { 75 while(l<q[i].l) t.modify(a[l].rank,-1),Ans-=t.query(a[l].rank-1),l++; 76 while(r>q[i].r) t.modify(a[r].rank,-1),Ans-=r-l-t.query(a[r].rank),r--; 77 while(l>q[i].l) l--,t.modify(a[l].rank,1),Ans+=t.query(a[l].rank-1); 78 while(r<q[i].r) r++,t.modify(a[r].rank,1),Ans+=r-l+1-t.query(a[r].rank); 79 ans[q[i].id]=Ans; 80 } 81 for(int i=0;i<m;i++) printf("%d\n",ans[i]); 82 return 0; 83 }