zoukankan      html  css  js  c++  java
  • UESTC 1425 Another LCIS

    也是一个求最长连续单调区间的问题,不同于HDU 3308LCIS的是,单点更新变成了区间成段增加,没关系同样的方法可破之。由于是成段更新,所以比更新区间小的区间是最大连续区间长度是不变的,所以更新sum[rt],lsum[rt],rsum[rt]只需要更新到这些区间,然后向上合并就行了。

    但是速度还是慢了一点699ms,总觉得哪里还有改进的地方。

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #define lson l,m,rt<<1
      5 #define rson m+1,r,rt<<1|1
      6 #define N 111111
      7 
      8 using namespace std;
      9 int sum[N<<2],lsum[N<<2],rsum[N<<2],add[N<<2],A[N];
     10 int n,q;
     11 
     12 void PushUp(int rt,int m,int mid)
     13 {
     14     lsum[rt]=lsum[rt<<1];
     15     rsum[rt]=rsum[rt<<1|1];
     16     int t=1;
     17     if(A[mid+1]>A[mid])
     18     {
     19         if(lsum[rt]==(m-(m>>1)))
     20             lsum[rt]+=lsum[rt<<1|1];
     21         if(rsum[rt]==(m>>1))
     22             rsum[rt]+=rsum[rt<<1];
     23             t=rsum[rt<<1]+lsum[rt<<1|1];
     24     }
     25     sum[rt]=max(t,max(sum[rt<<1],sum[rt<<1|1]));
     26 }
     27 
     28 void build(int l,int r,int rt)
     29 {
     30     if(l==r)
     31     {
     32         scanf("%d",A+l);
     33         sum[rt]=lsum[rt]=rsum[rt]=1;
     34         return ;
     35     }
     36     int m=(l+r)>>1;
     37     build(lson);
     38     build(rson);
     39     PushUp(rt,r-l+1,m);
     40 }
     41 
     42 void update(int L,int R,int l,int r,int rt)
     43 {
     44     if(L<=l&&R>=r)
     45         return;
     46     int m=(l+r)>>1;
     47     if(L<=m)
     48         update(L,R,lson);
     49     if(R>m)
     50         update(L,R,rson);
     51     PushUp(rt,r-l+1,m);
     52 }
     53 
     54 int query(int L,int R,int l,int r,int rt)
     55 {
     56     if(L<=l&&R>=r)
     57         return sum[rt];
     58     int m=(l+r)>>1;
     59     int ans=0;
     60     if(R<=m)
     61         ans=max(ans,query(L,R,lson));
     62     else if(L>m)
     63         ans=max(ans,query(L,R,rson));
     64     else
     65     {
     66         ans=max(ans,query(L,R,lson));
     67         ans=max(ans,query(L,R,rson));
     68         int ll,rr;
     69         if(m-L+1>=rsum[rt<<1])
     70             ll=rsum[rt<<1];
     71         else ll=m-L+1;
     72         if(R-m>=lsum[rt<<1|1])
     73             rr=lsum[rt<<1|1];
     74         else rr=R-m;
     75         if(A[m+1]>A[m])
     76             ans=max(ans,ll+rr);
     77     }
     78     return ans;
     79 }
     80 
     81 int main(void)
     82 {
     83     int T;
     84     int a,b,v;
     85     char op[3];
     86     for(int t=scanf("%d",&T); t<=T; t++)
     87     {
     88         memset(add,0,sizeof(add));
     89         printf("Case #%d:
    ",t);
     90         scanf("%d%d",&n,&q);
     91         build(1,n,1);
     92         while(q--)
     93         {
     94             scanf("%s",op);
     95             if(op[0]=='a')
     96             {
     97                 scanf("%d%d%d",&a,&b,&v);
     98                 for(int i=a;i<=b;i++)
     99                     A[i]+=v;
    100                 update(a,b,1,n,1);
    101             }
    102             else
    103             {
    104                 scanf("%d%d",&a,&b);
    105                 int ans=query(a,b,1,n,1);
    106                 printf("%d
    ",ans);
    107             }
    108         }
    109     }
    110     return 0;
    111 }

     方法二:看了下别人代码,发现每个区间可以用left[rt],right[rt]将区间端点值存起来,这样每次更新的时候更新端点值就可以了:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #define lson l,m,rt<<1
      5 #define rson m+1,r,rt<<1|1
      6 #define N 111111
      7 
      8 using namespace std;
      9 int sum[N<<2],lsum[N<<2],rsum[N<<2],add[N<<2],left[N<<2],right[N<<2];
     10 int n,q;
     11 
     12 void PushUp(int rt,int m)
     13 {
     14     left[rt]=left[rt<<1];
     15     right[rt]=right[rt<<1|1];
     16     lsum[rt]=lsum[rt<<1];
     17     rsum[rt]=rsum[rt<<1|1];
     18     int t=1;
     19     if(left[rt<<1|1]>right[rt<<1])
     20     {
     21         if(lsum[rt]==(m-(m>>1)))
     22             lsum[rt]+=lsum[rt<<1|1];
     23         if(rsum[rt]==(m>>1))
     24             rsum[rt]+=rsum[rt<<1];
     25         t=rsum[rt<<1]+lsum[rt<<1|1];
     26     }
     27     sum[rt]=max(t,max(sum[rt<<1],sum[rt<<1|1]));
     28 }
     29 void PushDown(int rt)
     30 {
     31     if(add[rt])//这里用来向下更新add[rt],
     32     {
     33         add[rt<<1]+=add[rt];
     34         add[rt<<1|1]+=add[rt];
     35         left[rt<<1]+=add[rt];
     36         right[rt<<1]+=add[rt];
     37         left[rt<<1|1]+=add[rt];
     38         right[rt<<1|1]+=add[rt];
     39         add[rt]=0;
     40     }
     41 
     42 }
     43 void build(int l,int r,int rt)
     44 {
     45     add[rt]=0;
     46     if(l==r)
     47     {
     48         scanf("%d",left+rt);
     49         right[rt]=left[rt];
     50         sum[rt]=lsum[rt]=rsum[rt]=1;
     51         return ;
     52     }
     53     int m=(l+r)>>1;
     54     build(lson);
     55     build(rson);
     56     PushUp(rt,r-l+1);
     57 }
     58 
     59 void update(int L,int R,int v,int l,int r,int rt)
     60 {
     61     if(L<=l&&R>=r)
     62     {
     63         left[rt]+=v;
     64         right[rt]+=v;
     65         add[rt]+=v;
     66         return;
     67     }
     68     int m=(l+r)>>1;
     69     PushDown(rt);
     70     if(L<=m)
     71         update(L,R,v,lson);
     72     if(R>m)
     73         update(L,R,v,rson);
     74     PushUp(rt,r-l+1);
     75 }
     76 
     77 int query(int L,int R,int l,int r,int rt)
     78 {
     79     if(L<=l&&R>=r)
     80         return sum[rt];
     81     PushDown(rt);
     82     int m=(l+r)>>1;
     83     int ans=0;
     84     if(R>m)
     85         ans=max(ans,query(L,R,rson));
     86     if(L<=m)
     87         ans=max(ans,query(L,R,lson));
     88     if(left[rt<<1|1]>right[rt<<1]&&L<=m&&R>m)
     89     {
     90         int ll,rr;
     91         if(m-L+1>=rsum[rt<<1])
     92             ll=rsum[rt<<1];
     93         else ll=m-L+1;
     94         if(R-m>=lsum[rt<<1|1])
     95             rr=lsum[rt<<1|1];
     96         else rr=R-m;
     97         ans=max(ans,ll+rr);
     98     }
     99     return ans;
    100 }
    101 
    102 int main(void)
    103 {
    104     int T;
    105     int a,b,v;
    106     char op[3];
    107     for(int t=scanf("%d",&T); t<=T; t++)
    108     {
    109         memset(add,0,sizeof(add));
    110         printf("Case #%d:
    ",t);
    111         scanf("%d%d",&n,&q);
    112         build(1,n,1);
    113         while(q--)
    114         {
    115             scanf("%s",op);
    116             if(op[0]=='a')
    117             {
    118                 scanf("%d%d%d",&a,&b,&v);
    119                 update(a,b,v,1,n,1);
    120             }
    121             else
    122             {
    123                 scanf("%d%d",&a,&b);
    124                 int ans=query(a,b,1,n,1);
    125                 printf("%d
    ",ans);
    126             }
    127         }
    128     }
    129     return 0;
    130 }
  • 相关阅读:
    jquery中$.get()提交和$.post()提交有区别吗?
    数据库连接池的原理。为什么要使用连接池。
    execute,executeQuery,executeUpdate的区别是什么?
    数据库的三级模式与二级映像
    KMP算法(超容易理解的next数组求法)
    软件危机(含通俗理解帮助记忆)
    O(1)复杂度求一个栈的最小值
    操作系统进程状态模型
    判断单链表是否有环,如果有环则找到其环的入口
    两个单链表判断是否相交
  • 原文地址:https://www.cnblogs.com/rootial/p/3251781.html
Copyright © 2011-2022 走看看