3289: Mato的文件管理
Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 3007 Solved: 1272
[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次移到最后。
————————————————————————————————————————————————————————————————————————————
思路:
交换次数也就是逆序对的个数。
明显莫队并以树状数组或线段树来维护逆序对的个数。莫队每增加或减少一个值时,计算增加或减少逆序对的个数,OK!
道理很简单,但是我用了多种线段树的写法,都TLE,树状数组一次过了!
哪位大神看一下我的线段树,那里导致的超时!感谢!
————————————————————————————————————————————————————————————————————————————
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 const int maxn=5e4+7; 5 typedef long long ll; 6 int n,m; 7 int zl[maxn],hash[maxn]; 8 struct que 9 { 10 int l,r,id,belong; 11 }q[maxn]; 12 ll da[maxn],ans; 13 int l,r,siz,xx; 14 int sz[maxn]; 15 int dat[maxn<<2],lll[maxn<<2],rr[maxn<<2]; 16 int js=0; 17 bool cmp(que a,que b) 18 { 19 return a.belong<b.belong || (a.belong==b.belong && a.r<b.r); 20 } 21 void readint(int &x) 22 { 23 char c=getchar(); 24 int f=1; 25 for(;c>'9'||c<'0';c=getchar())if(c=='-')f=-f; 26 x=0; 27 for(;c<='9' && c>='0';c=getchar())x=(x<<1)+(x<<3)+c-'0'; 28 x=x*f; 29 } 30 inline int lowbit(int x) 31 { 32 return x&(-x); 33 } 34 int fin(int ps) 35 { 36 int tp=0; 37 for(;ps>0;ps-=lowbit(ps))tp+=sz[ps]; 38 return tp; 39 } 40 void update(int ps,int x) 41 { 42 for(;ps<=siz;ps+=lowbit(ps))sz[ps]+=x; 43 } 44 void add0(int ps) 45 { 46 ps=zl[ps]; 47 ans+=fin(ps-1); 48 update(ps,1); 49 } 50 void del0(int ps) 51 { 52 ps=zl[ps]; 53 ans-=fin(ps-1); 54 update(ps,-1); 55 } 56 void add1(int ps) 57 { 58 ps=zl[ps]; 59 ans+=xx-fin(ps); 60 update(ps,1); 61 } 62 void del1(int ps) 63 { 64 ps=zl[ps]; 65 ans-=xx-fin(ps); 66 update(ps,-1); 67 } 68 int main() 69 { 70 readint(n); 71 for(int i=1;i<=n;i++) 72 { 73 readint(zl[i]);hash[i]=zl[i]; 74 } 75 sort(hash+1,hash+1+n); 76 siz=unique(hash+1,hash+1+n)-hash-1; 77 for(int i=1;i<=n;i++) 78 { 79 zl[i]=lower_bound(hash+1,hash+1+siz,zl[i])-hash; 80 } 81 readint(m); 82 int bks=sqrt(n+0.5); 83 for(int i=0;i<m;i++) 84 { 85 readint(q[i].l);readint(q[i].r); 86 q[i].id=i;q[i].belong=(q[i].l-1)/bks; 87 } 88 sort(q,q+m,cmp); 89 memset(sz,0,sizeof(sz)); 90 l=2;r=1;ans=0; 91 for(int i=0;i<m;i++) 92 { 93 while(l<q[i].l) 94 { 95 del0(l);l++;xx=r-l+1; 96 } 97 while(l>q[i].l) 98 { 99 l--;add0(l);xx=r-l+1; 100 } 101 while(r<q[i].r) 102 { 103 r++;add1(r); xx=r-l+1; 104 } 105 while(r>q[i].r) 106 { 107 del1(r);r--;xx=r-l+1; 108 } 109 da[q[i].id]=ans; 110 } 111 for(int i=0;i<m;i++)printf("%d ",da[i]); 112 return 0; 113 }
下面是线段树没过的,请大神指点!
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 const int maxn=5e4+7; 5 typedef long long ll; 6 int n,m; 7 int zl[maxn],hash[maxn]; 8 struct que 9 { 10 int l,r,id,belong; 11 }q[maxn]; 12 ll da[maxn],ans; 13 int l,r,siz; 14 int dat[maxn<<2],lll[maxn<<2],rr[maxn<<2]; 15 int js=0; 16 bool cmp(que a,que b) 17 { 18 return a.belong<b.belong || (a.belong==b.belong && a.r<b.r); 19 } 20 void readint(int &x) 21 { 22 char c=getchar(); 23 int f=1; 24 for(;c>'9'||c<'0';c=getchar())if(c=='-')f=-f; 25 x=0; 26 for(;c<='9' && c>='0';c=getchar())x=(x<<1)+(x<<3)+c-'0'; 27 x=x*f; 28 } 29 void build(int cur,int l,int r) 30 { 31 dat[cur]=0; 32 lll[cur]=l;rr[cur]=r; 33 if(l==r)return ; 34 int mid=(l+r)/2; 35 build(cur<<1,l,mid); 36 build((cur<<1)|1,mid+1,r); 37 } 38 int fin(int cur,int l,int r) 39 { 40 if(r<l)return 0; 41 if(l<=lll[cur] && rr[cur]<=r)return dat[cur]; 42 int mid=(lll[cur]+rr[cur])>>1; 43 int tp=0; 44 if(l<=mid)tp+=fin(cur<<1,l,r); 45 if(r>mid)tp+=fin((cur<<1)|1,l,r); 46 return tp; 47 } 48 void update(int cur,int ps,int x) 49 { 50 dat[cur]+=x; 51 if(lll[cur]==rr[cur])return ; 52 int mid=(lll[cur]+rr[cur])>>1; 53 if(ps<=mid)update(cur<<1,ps,x); 54 else update((cur<<1)|1,ps,x); 55 } 56 void add0(int ps) 57 { 58 ps=zl[ps]; 59 ans+=fin(1,1,ps-1); 60 update(1,ps,1); 61 } 62 void del0(int ps) 63 { 64 ps=zl[ps]; 65 ans-=fin(1,1,ps-1); 66 update(1,ps,-1); 67 } 68 void add1(int ps) 69 { 70 ps=zl[ps]; 71 ans+=fin(1,ps+1,siz); 72 update(1,ps,1); 73 } 74 void del1(int ps) 75 { 76 ps=zl[ps]; 77 ans-=fin(1,ps+1,siz); 78 update(1,ps,-1); 79 } 80 int main() 81 { 82 readint(n); 83 for(int i=1;i<=n;i++) 84 { 85 readint(zl[i]);hash[i]=zl[i]; 86 } 87 sort(hash+1,hash+1+n); 88 siz=unique(hash+1,hash+1+n)-hash-1; 89 for(int i=1;i<=n;i++) 90 { 91 zl[i]=lower_bound(hash+1,hash+1+siz,zl[i])-hash; 92 } 93 readint(m); 94 int bks=sqrt(n+0.5); 95 for(int i=0;i<m;i++) 96 { 97 readint(q[i].l);readint(q[i].r); 98 q[i].id=i;q[i].belong=(q[i].l-1)/bks; 99 } 100 sort(q,q+m,cmp); 101 build(1,1,siz); 102 l=2;r=1;ans=0; 103 for(int i=0;i<m;i++) 104 { 105 while(l<q[i].l) 106 { 107 del0(l);l++; 108 } 109 while(l>q[i].l) 110 { 111 l--;add0(l); 112 } 113 while(r<q[i].r) 114 { 115 r++;add1(r); 116 } 117 while(r>q[i].r) 118 { 119 del1(r);r--; 120 } 121 da[q[i].id]=ans; 122 } 123 for(int i=0;i<m;i++)printf("%d ",da[i]); 124 return 0; 125 }