码迷,mamicode.com
首页 > 编程语言 > 详细

BZOJ3289[JZYZOJP2018]: Mato的文件管理 莫队+树状数组+离散化

时间:2017-11-04 18:06:44      阅读:191      评论:0      收藏:0      [点我收藏+]

标签:hang   tab   std   inpu   height   习惯   方式   main   unique   

     
  描述 Description  
  Mato同学从各路神犇以各种方式(你们懂的)收集了许多资料,这些资料一共有n份,每份有一个大小和一个编号。为了防止他人偷拷,这些资料都是加密过的,只能用Mato自己写的程序才能访问。Mato每天随机选一个区间[l,r],他今天就看编号在此区间内的这些资料。Mato有一个习惯,他总是从文件大小从小到大看资料。他先把要看的文件按编号顺序依次拷贝出来,再用他写的排序程序给文件大小排序。排序程序可以在1单位时间内交换2个相邻的文件(因为加密需要,不能随机访问)。Mato想要使文件交换次数最小,你能告诉他每天需要交换多少次吗?
     
     
  输入格式 Input Format  
  第一行一个正整数n,表示Mato的资料份数。
第二行由空格隔开的n个正整数,第i个表示编号为i的资料的大小。
第三行一个正整数q,表示Mato会看几天资料。
之后q行每行两个正整数l、r,表示Mato这天看[l,r]区间的文件。
     
     
  输出格式 Output Format  
  q行,每行一个正整数,表示Mato这天需要交换的次数。
     

     
  时间限制 Time Limitation  
  1s
   

     
  注释 Hint  
  Hint

n,q <= 50000

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

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

 

 

离散化可以看我上一篇写的那个离散化blahblah什么的.......算是莫队板子
和离散化板子和树状数组板子放到一起的板子题....
树状数组求逆序对即可


代码

 

技术分享
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<algorithm>
 6 using namespace std;
 7 int n,q;
 8 int a[50010]={};//原本的文件
 9 int b[50010]={};//离散化媒介
10 int bel[50010]={};//询问块
11 int tr[50010]={};//树状数组
12 int ans[50010]={};
13 struct nod{
14     int x,y;
15     int id;
16 }e[50010];
17 int sz;
18 bool mmp(nod aa,nod bb){
19     if(bel[aa.x]==bel[bb.x]){
20         if(aa.y==bb.y){
21             return aa.x<bb.x;
22         }
23         return aa.y<bb.y;
24     }
25     return bel[aa.x]<bel[bb.x];
26 }
27 inline int lowbit(int x){
28     return x&-x;
29 }
30 inline int sum(int x){
31     int ret = 0;
32     while(x>0){
33         ret+=tr[x];
34         x-=lowbit(x);
35     }
36     return ret;
37 }
38 inline void add(int x,int v){
39     while(x<=50005){
40         tr[x]+=v;
41         x+=lowbit(x);
42     }
43 }
44 void work(){
45     int l=1,r=0;
46     int an=0;
47     for(int i=1;i<=q;i++){
48         while(l>e[i].x){
49             l--;
50             an+=sum(a[l]-1);
51             add(a[l],1);
52         }
53         while(r<e[i].y){            
54             r++;
55             an+=sum(50005)-sum(a[r]);
56             add(a[r],1);
57         }
58         while(l<e[i].x){
59             add(a[l],-1);
60             an-=sum(a[l]-1);
61             l++;
62         }
63         while(r>e[i].y){
64             add(a[r],-1);
65             an-=sum(50005)-sum(a[r]);
66             r--;
67         }
68         ans[e[i].id]=an;
69     }
70     for(int i=1;i<=q;i++){
71         printf("%d\n",ans[i]);
72     }
73 }
74 int main(){
75     //freopen("wtf.in","r",stdin);
76     scanf("%d",&n);
77     for(int i=1;i<=n;i++){
78         scanf("%d",&a[i]);
79         b[i]=a[i];
80     }
81     sort(b+1,b+n+1);
82     int size=unique(b+1,b+n+1)-b-1;
83     for(int i=1;i<=n;i++){
84         a[i]=lower_bound(b+1,b+size+1,a[i])-b;
85     }
86     scanf("%d",&q);
87     sz=(int)sqrt((double)q);
88     for(int i=1;i<=q;i++){
89         bel[i]=(i-1)/sz+1;
90     }
91     for(int i=1;i<=q;i++){
92         scanf("%d%d",&e[i].x,&e[i].y);
93         e[i].id=i;
94     }
95     sort(e+1,e+1+q,mmp);
96     work();
97     return 0;
98 }
View Code

 

BZOJ3289[JZYZOJP2018]: Mato的文件管理 莫队+树状数组+离散化

标签:hang   tab   std   inpu   height   习惯   方式   main   unique   

原文地址:http://www.cnblogs.com/137shoebills/p/7783801.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!