3289: Mato的文件管理

Time Limit: 40 Sec  Memory Limit: 128 MB
Submit: 2819  Solved: 1185

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

Sample Output

0
2


HINT

Hint

n,q <= 50000

样例解释:第一天,Mato不需要交换

第二天,Mato可以把2号交换2次移到最后。

Source

 

【分析】

  好蠢一直在想整体二分怎么搞。。然后搞不了。。。

  换作以前一定立马用莫队了吧。。

  【能整个区间搞的一定能用莫队带个$\sqrt n$?

 

  一开始傻傻地打线段树果断T了。。

 

【BZOJ 3289】 3289: Mato的文件管理 (莫队)_文件大小【BZOJ 3289】 3289: Mato的文件管理 (莫队)_文件大小_02
  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<cstring>
  4 #include<iostream>
  5 #include<algorithm>
  6 #include<cmath>
  7 using namespace std;
  8 #define Maxn 100010
  9 #define INF 0xfffffff
 10 
 11 int a[Maxn],sq;
 12 
 13 struct node
 14 {
 15     int l,r,lc,rc,sm;
 16 }tr[Maxn];
 17 
 18 struct nnode{int x,y,id,ans;}t[Maxn];
 19 
 20 bool cmp(nnode x,nnode y) {return x.x<y.x;}
 21 bool cmp2(nnode x,nnode y) {return (x.x/sq==y.x/sq)?(x.y<y.y):(x.x/sq<y.x/sq);}
 22 bool cmp3(nnode x,nnode y) {return x.id<y.id;}
 23 
 24 int n;
 25 
 26 int mx[Maxn],mn[Maxn];
 27 
 28 void change(int x,int y)
 29 {
 30     for(int i=x;i<=n;i+=i&(-i)) mn[i]+=y;
 31     for(int i=x;i>=1;i-=i&(-i)) mx[i]+=y;
 32 }
 33 
 34 int query(int p,int x)
 35 {
 36     int ans=0;
 37     if(!p)
 38     {
 39         for(int i=x;i<=n;i+=i&(-i)) ans+=mx[i];
 40     }else{
 41         
 42         for(int i=x;i>=1;i-=i&(-i)) ans+=mn[i];
 43     }
 44     return ans;
 45 }
 46 
 47 int main()
 48 {
 49     int q;
 50     scanf("%d",&n);
 51     for(int i=1;i<=n;i++)
 52     {
 53         int x;
 54         scanf("%d",&x);
 55         t[i].x=x;t[i].id=i;
 56     }
 57     sort(t+1,t+1+n,cmp);
 58     int p=1;a[t[1].id]=1;
 59     for(int i=2;i<=n;i++)
 60     {
 61         if(t[i].x!=t[i-1].x) p++;
 62         a[t[i].id]=p;
 63     }
 64     scanf("%d",&q);
 65     for(int i=1;i<=q;i++)
 66     {
 67         int x,y;
 68         scanf("%d%d",&t[i].x,&t[i].y);
 69         t[i].id=i;
 70     }
 71     sq=(int)ceil(sqrt((double)n));
 72     sort(t+1,t+1+q,cmp2);
 73     int l=1,r=0;
 74     int nans=0;
 75     memset(mn,0,sizeof(mn));
 76     memset(mx,0,sizeof(mx));
 77     for(int i=1;i<=q;i++)
 78     {
 79         while(r<t[i].y)
 80         {
 81             nans+=query(0,a[r+1]+1);
 82             change(a[r+1],1);
 83             r++;
 84         }
 85         while(l>t[i].x)
 86         {
 87             nans+=query(1,a[l-1]-1);
 88             change(a[l-1],1);
 89             l--;
 90         }
 91         while(l<t[i].x)
 92         {
 93             nans-=query(1,a[l]-1);
 94             change(a[l],-1);
 95             l++;
 96         }
 97         while(r>t[i].y)
 98         {
 99             nans-=query(0,a[r]+1);
100             change(a[r],-1);
101             r--;
102         }
103         t[i].ans=nans;
104     }
105     sort(t+1,t+1+q,cmp3);
106     for(int i=1;i<=q;i++) printf("%d\n",t[i].ans);
107     return 0;
108 }
View Code

 

2017-03-25 15:43:39