bzoj3289 mato的文件管理

3289: Mato的文件管理

Time Limit: 40 Sec  Memory Limit: 128 MB
Submit: 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

Sample Output

0
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\n",da[i]);
112     return 0;
113 }
View Code

下面是线段树没过的,请大神指点!

  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\n",da[i]);
124     return 0;
125 }
View Code

 

posted on 2017-05-23 15:52  gryzy  阅读(165)  评论(0编辑  收藏  举报

导航