zoukankan      html  css  js  c++  java
  • HDU 3911 区间合并求最大长度的问题

    http://vjudge.net/problem/viewProblem.action?id=21557

    题目大意:

    每进行一次颜色改变都可以把一段区间内的黑石头变成白石头,白石头变成黑石头,最后问区间内黑石头连续的最大长度

    这里我们可以用rev[]作为lazy标记,每次进行改变,rev[]^1

    因为有黑白两种石头,我们求连续区间,需要维护黑,白两种石头的左侧最多,右侧最多和全部最多,所以我们这里可以用一个二维数组进行描述

    每次做出改变,只要将黑白石头的值进行交换即可就方便了很多

    对于最后访问的时候做的区间合并。。。。我确实有点拙计了,最后是学长帮忙改正的。。。。

    还是有点只会套模板的嫌疑Orz,关键模板的代码是不考虑处在两个不同的区间进行合并的情况的,所以最后在所有 单个区间的情况判断完后,我们

    要把左子树的右侧和右子树的左侧合并到一起,因为可能会超过访问范围,所以这里用的是:

    ans = max(ans,min(mid-s+1,rc[ls][1])+min(t-mid,lc[rs][1]));

    在内部取个最小值。

    在此将自己拙计的query函数和正确的query函数进行一下对比:

    /*
    void query(int cur ,int x,int y,int s,int t,int &ans)
    {
        int mid=(x+y)/2,ls=cur<<1,rs=cur<<1|1;
        if(x>=s&&y<=t){
            ans+=mc[cur][1];
            return;
        }
        push_down(cur,x,y);
        if(mid>=s) query(L,s,t,ans);
        if(mid+1<=t) query(R,s,t,ans);
    }*/
    
    int query(int cur,int x,int y,int s,int t){
        int mid=(x+y)/2,ls=cur<<1,rs=cur<<1|1;
        if(x>=s&&y<=t){
            return mc[cur][1];
        }
        push_down(cur,x,y);
        int ans = 0;
        if(mid>=s) ans = max(ans,query(L,s,t));
        if(mid+1<=t) ans = max(ans,query(R,s,t));
        ans = max(ans,min(mid-s+1,rc[ls][1])+min(t-mid,lc[rs][1]));
        return ans;
    }

    总代码如下:

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <algorithm>
      4 using namespace std;
      5 #define N 100010
      6 #define L ls,x,mid
      7 #define R rs,mid+1,y
      8 int color[N],rev[N<<2],lc[N<<2][2],rc[N<<2][2],mc[N<<2][2];
      9 void push_up(int cur,int x,int y)
     10 {
     11     int mid=(x+y)/2,ls=cur<<1,rs=cur<<1|1;
     12     for(int i=0;i<2;i++){
     13         lc[cur][i]=lc[ls][i],rc[cur][i]=rc[rs][i];
     14         mc[cur][i]=max(mc[ls][i],mc[rs][i]);
     15         mc[cur][i]=max(mc[cur][i],rc[ls][i]+lc[rs][i]);
     16         if(lc[ls][i]==mid-x+1) lc[cur][i]=lc[ls][i]+lc[rs][i];
     17         if(rc[rs][i]==y-mid) rc[cur][i]=rc[rs][i]+rc[ls][i];
     18     }
     19 }
     20 void push_down(int cur,int x,int y)
     21 {
     22     int ls=cur<<1,rs=cur<<1|1;
     23     if(rev[cur]){
     24         rev[ls]^=1,rev[rs]^=1;
     25 
     26         swap(lc[ls][0],lc[ls][1]);
     27         swap(lc[rs][0],lc[rs][1]);
     28 
     29         swap(rc[ls][0],rc[ls][1]);
     30         swap(rc[rs][0],rc[rs][1]);
     31 
     32         swap(mc[ls][0],mc[ls][1]);
     33         swap(mc[rs][0],mc[rs][1]);
     34 
     35         rev[cur]=0;
     36     }
     37 }
     38 void build(int cur,int x,int y)
     39 {
     40     int mid=(x+y)/2,ls=cur<<1,rs=cur<<1|1;
     41     rev[cur]=0;
     42     if(x==y){
     43         lc[cur][0]=rc[cur][0]=mc[cur][0]=color[x]^1;
     44         lc[cur][1]=rc[cur][1]=mc[cur][1]=color[x];
     45         return;
     46     }
     47     build(L);
     48     build(R);
     49     push_up(cur,x,y);
     50 }
     51 void update(int cur,int x,int y,int s,int t)
     52 {
     53     int mid=(x+y)/2,ls=cur<<1,rs=cur<<1|1;
     54     if(x>=s&&y<=t){
     55         swap(lc[cur][0],lc[cur][1]);
     56         swap(rc[cur][0],rc[cur][1]);
     57         swap(mc[cur][0],mc[cur][1]);
     58         rev[cur]^=1;
     59         return;
     60     }
     61     push_down(cur,x,y);
     62     if(mid>=s) update(L,s,t);
     63     if(mid+1<=t) update(R,s,t);
     64     push_up(cur,x,y);
     65 }
     66 /*
     67 void query(int cur ,int x,int y,int s,int t,int &ans)
     68 {
     69     int mid=(x+y)/2,ls=cur<<1,rs=cur<<1|1;
     70     if(x>=s&&y<=t){
     71         ans+=mc[cur][1];
     72         return;
     73     }
     74     push_down(cur,x,y);
     75     if(mid>=s) query(L,s,t,ans);
     76     if(mid+1<=t) query(R,s,t,ans);
     77 }*/
     78 
     79 int query(int cur,int x,int y,int s,int t){
     80     int mid=(x+y)/2,ls=cur<<1,rs=cur<<1|1;
     81     if(x>=s&&y<=t){
     82         return mc[cur][1];
     83     }
     84     push_down(cur,x,y);
     85     int ans = 0;
     86     if(mid>=s) ans = max(ans,query(L,s,t));
     87     if(mid+1<=t) ans = max(ans,query(R,s,t));
     88     ans = max(ans,min(mid-s+1,rc[ls][1])+min(t-mid,lc[rs][1]));
     89     return ans;
     90 }
     91 int main()
     92 {
     93     int n,m,op,a,b;
     94     while(scanf("%d",&n)!=EOF){
     95         for(int i=1;i<=n;i++) scanf("%d",&color[i]);
     96         build(1,1,n);
     97         scanf("%d",&m);
     98         for(int i=0;i<m;i++){
     99             scanf("%d%d%d",&op,&a,&b);
    100             if(op) update(1,1,n,a,b);
    101             else{
    102                 //int ans=0;
    103                 //query(1,1,n,a,b,ans);
    104                 printf("%d
    ",query(1,1,n,a,b));
    105             }
    106         }
    107     }
    108     return 0;
    109 }
    View Code
  • 相关阅读:
    防火墙实践
    提高工作效率的小技巧
    网络系统参数配置
    linux 文件截取
    python (1) 还不是大全的小问题
    iptables 命令记录
    网络常用端口
    HTTP时间指标
    错误集锦
    access数据库调用
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/3898581.html
Copyright © 2011-2022 走看看