码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 3911 区间合并求最大长度的问题

时间:2014-08-08 09:33:45      阅读:352      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   os   io   for   art   

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;
}

总代码如下:

bubuko.com,布布扣
  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\n",query(1,1,n,a,b));
105             }
106         }
107     }
108     return 0;
109 }
View Code

 

HDU 3911 区间合并求最大长度的问题,布布扣,bubuko.com

HDU 3911 区间合并求最大长度的问题

标签:style   blog   http   color   os   io   for   art   

原文地址:http://www.cnblogs.com/CSU3901130321/p/3898581.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!