Bzoj 3289: Mato的文件管理 莫队,树状数组,逆序对,离散化,分块
3289: Mato的文件管理
Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 1539 Solved: 665
[Submit][Status][Discuss]
Description
Mato同学从各路神犇以各种方式(你们懂的)收集了许多资料,这些资料一共有n份,每份有一个大小和一个编号。为了防止他人偷拷,这些资料都是加密过的,只能用Mato自己写的程序才能访问。Mato每天随机选一个区间[l,r],他今天就看编号在此区间内的这些资料。Mato有一个习惯,他总是从文件大小从小到大看资料。他先把要看的文件按编号顺序依次拷贝出来,再用他写的排序程序给文件大小排序。排序程序可以在1单位时间内交换2个相邻的文件(因为加密需要,不能随机访问)。Mato想要使文件交换次数最小,你能告诉他每天需要交换多少次吗?
Input
第一行一个正整数n,表示Mato的资料份数。
第二行由空格隔开的n个正整数,第i个表示编号为i的资料的大小。
第三行一个正整数q,表示Mato会看几天资料。
之后q行每行两个正整数l、r,表示Mato这天看[l,r]区间的文件。
Output
q行,每行一个正整数,表示Mato这天需要交换的次数。
Sample Input
4
1 4 2 3
2
1 2
2 4
1 4 2 3
2
1 2
2 4
Sample Output
0
2
2
HINT
Hint
n,q <= 50000
样例解释:第一天,Mato不需要交换
第二天,Mato可以把2号交换2次移到最后。
Source
题解:
多次查询,不修改,一看就是莫队。。。
每次交换相邻的元素,这不是逆序对吗。。。
于是,直接胡搞一个莫队+逆序对。。。
逆序对可以用树状数组维护,可以看一下我的上一篇博客http://www.cnblogs.com/Var123/p/5300334.html
Poj 2299就是求逆序对。(可以先做一下)
1A了很开心。。。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define MAXN 50010 4 int N,sz[MAXN],color[MAXN],BIT[MAXN],pos[MAXN],ans1[MAXN]; 5 struct node 6 { 7 int l,r,id; 8 }q[MAXN]; 9 int read() 10 { 11 int s=0,fh=1;char ch=getchar(); 12 while(ch<'0'||ch>'9'){if(ch=='-')fh=-1;ch=getchar();} 13 while(ch>='0'&&ch<='9'){s=s*10+(ch-'0');ch=getchar();} 14 return s*fh; 15 } 16 bool cmp(node aa,node bb) 17 { 18 if(pos[aa.l]==pos[bb.l])return aa.r<bb.r; 19 return aa.l<bb.l; 20 } 21 int Lowbit(int o){return o&(-o);} 22 void Update(int o,int o1) 23 { 24 while(o<=N) 25 { 26 BIT[o]+=o1; 27 o+=Lowbit(o); 28 } 29 } 30 int Sum(int o) 31 { 32 int sum=0; 33 while(o>0) 34 { 35 sum+=BIT[o]; 36 o-=Lowbit(o); 37 } 38 return sum; 39 } 40 int main() 41 { 42 int L,R,Q,i,ans,block,wz,tot; 43 N=read(); 44 for(i=1;i<=N;i++)sz[i]=read(),color[i]=sz[i]; 45 sort(sz+1,sz+N+1); 46 tot=unique(sz+1,sz+N+1)-(sz+1); 47 block=(int)sqrt(N); 48 Q=read(); 49 for(i=1;i<=Q;i++) 50 { 51 q[i].l=read();q[i].r=read();q[i].id=i; 52 } 53 for(i=1;i<=N;i++)pos[i]=(int)(i-1)/block+1; 54 L=1;R=0;memset(BIT,0,sizeof(BIT)); 55 sort(q+1,q+Q+1,cmp); 56 ans=0; 57 memset(ans1,0,sizeof(ans1)); 58 for(i=1;i<=Q;i++) 59 { 60 while(L<q[i].l) 61 { 62 wz=lower_bound(sz+1,sz+tot+1,color[L])-sz; 63 Update(wz,-1); 64 ans-=Sum(wz-1); 65 L++; 66 //Update(wz,-1); 67 } 68 while(L>q[i].l) 69 { 70 L--; 71 wz=lower_bound(sz+1,sz+tot+1,color[L])-sz; 72 ans+=Sum(wz-1); 73 Update(wz,1); 74 } 75 while(R<q[i].r) 76 { 77 R++; 78 wz=lower_bound(sz+1,sz+tot+1,color[R])-sz; 79 ans+=(Sum(N)-Sum(wz)); 80 Update(wz,1); 81 } 82 while(R>q[i].r) 83 { 84 wz=lower_bound(sz+1,sz+tot+1,color[R])-sz; 85 ans-=(Sum(N)-Sum(wz)); 86 Update(wz,-1); 87 R--; 88 } 89 ans1[q[i].id]=ans; 90 } 91 for(i=1;i<=Q;i++)printf("%d\n",ans1[i]); 92 return 0; 93 }