1. 程式人生 > >BZOJ3289[JZYZOJP2018]: Mato的文件管理 莫隊+樹狀數組+離散化

BZOJ3289[JZYZOJP2018]: Mato的文件管理 莫隊+樹狀數組+離散化

b- scanf fff 次數 tdi des ++ esc 隨機

描述 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的文件管理 莫隊+樹狀數組+離散化