zoukankan      html  css  js  c++  java
  • 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
    ",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
    ",da[i]);
    124     return 0;
    125 }
    View Code
  • 相关阅读:
    [公告]博客园新服务器已下订单
    清除SearchNet.exe
    [新闻]微软将在2007年发布的Office产品阵容
    卸载Internet Explorer 7 Beta 2 Preview引起原来的IE无法正常使用
    博客园准备购买新服务器
    [微软活动公告]微软最有价值专家(MVP)四月份在线申请开始了
    [公告]今晚数据库迁移至新服务器
    请wz不要把别人的文章当作自己的文章发表
    SQL Server 2000 To SQL Server 2005
    [公告]博客园数据库已成功迁移至新服务器
  • 原文地址:https://www.cnblogs.com/gryzy/p/6894451.html
Copyright © 2011-2022 走看看