|
|
|
|
描述 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这天需要交换的次数。 |
|
|
|
|
|
|
|
注释 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 }
时间: 2024-11-08 10:42:58