zoukankan      html  css  js  c++  java
  • BZOJ 1858

    1858: [Scoi2010]序列操作

    Time Limit: 10 Sec  Memory Limit: 64 MB
    Submit: 2489  Solved: 1228
    [Submit][Status][Discuss]

    Description

    lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要么是1,现在对于这个序列有五种变换操作和询问操作:
    0 a b 把[a, b]区间内的所有数全变成0
    1 a b 把[a, b]区间内的所有数全变成1
    2 a b 把[a,b]区间内的所有数全部取反,也就是说把所有的0变成1,把所有的1变成0
    3 a b 询问[a, b]区间内总共有多少个1
    4 a b 询问[a, b]区间内最多有多少个连续的1
    对于每一种询问操作,lxhgww都需要给出回答,聪明的程序员们,你们能帮助他吗?

    Input

    输入数据第一行包括2个数,n和m,分别表示序列的长度和操作数目 第二行包括n个数,表示序列的初始状态 接下来m行,每行3个数,op, a, b,(0<=op<=4,0<=a<=b<n)表示对于区间[a, b]执行标号为op的操作="" <="" div="">

    Output

    对于每一个询问操作,输出一行,包括1个数,表示其对应的答案

    Sample Input

    10 10
    0 0 0 1 1 0 1 0 1 1
    1 0 2
    3 0 5
    2 2 2
    4 0 4
    0 3 6
    2 3 7
    4 2 8
    1 0 5
    0 5 6
    3 3 9

    Sample Output

    5
    2
    6
    5

    HINT

    对于30%的数据,1<=n, m<=1000
    对于100%的数据,1<=n, m<=100000

    Source

    Day2

    Solution

    直接用线段树维护

    Code

      1 #include<stdio.h>
      2 #include<iostream>
      3 #include<cstring>
      4 #include<cmath>
      5 #include<algorithm>
      6 #define N 100005
      7 using namespace std;
      8 int n,m;
      9 struct seg
     10 {
     11     int l1,l0,r1,r0,m1,m0,s1,s0;
     12     int l,r;
     13     int rev,c,full;
     14 }t[N<<2];
     15 void rev(int k)
     16 {
     17     swap(t[k].l1,t[k].l0);
     18     swap(t[k].r1,t[k].r0);
     19     swap(t[k].m1,t[k].m0);
     20     swap(t[k].s1,t[k].s0);
     21     if(t[k].full!=-1)t[k].full^=1;
     22 }
     23 void color(int k,int v)
     24 {
     25     t[k].rev=0;
     26     int s=t[k].r-t[k].l+1;
     27     if(v)
     28     {
     29         t[k].s0=t[k].m0=t[k].l0=t[k].r0=0;
     30         t[k].s1=t[k].m1=t[k].l1=t[k].r1=s;
     31     }else
     32     {
     33         t[k].s0=t[k].m0=t[k].l0=t[k].r0=s;
     34         t[k].s1=t[k].m1=t[k].l1=t[k].r1=0;
     35     }
     36     t[k].full=v;
     37 }
     38 /*
     39 seg merge(seg a,seg b)
     40 {
     41     seg tmp;tmp.l=a.l;tmp.r=b.r;
     42     tmp.rev=0;tmp.c=-1;
     43     tmp.l0=a.l0;tmp.l1=a.l1;
     44     tmp.r0=b.r0;tmp.r1=b.r1;
     45     tmp.m0=max(max(a.m0,b.m0),a.r0+b.l0);
     46     tmp.m1=max(max(a.m1,b.m1),a.r1+b.l1);
     47     tmp.s0=a.s0+b.s0;
     48     tmp.s1=a.s1+b.s1;
     49     if(a.full==0)tmp.l0=a.m0+b.l0;
     50     else if(a.full==1)tmp.l1=a.m1+b.l1;
     51     if(b.full==0)tmp.r0=a.r0+b.m0;
     52     else if(b.full==1)tmp.r1=a.r1+b.m1;
     53     if(a.full=b.full)tmp.full=a.full;
     54     else tmp.full=-1;
     55     return tmp;
     56 }*/
     57 seg merge(seg a,seg b) 
     58 {
     59     seg tmp;tmp.l=a.l;tmp.r=b.r;
     60     tmp.rev=0;tmp.c=-1;
     61     tmp.l0=a.l0;tmp.l1=a.l1;
     62     tmp.r0=b.r0;tmp.r1=b.r1;
     63     tmp.m0=max(max(a.m0,b.m0),a.r0+b.l0);
     64     tmp.m1=max(max(a.m1,b.m1),a.r1+b.l1);
     65     tmp.s0=a.s0+b.s0;
     66     tmp.s1=a.s1+b.s1;
     67     if(a.full==0)tmp.l0=a.m0+b.l0;
     68     else if(a.full==1)tmp.l1=a.m1+b.l1;
     69     if(b.full==0)tmp.r0=b.m0+a.r0;
     70     else if(b.full==1)tmp.r1=b.m1+a.r1;
     71     if(a.full==b.full)tmp.full=a.full;
     72     else tmp.full=-1;
     73     return tmp;
     74 }
     75 void pushup(int k)
     76 {t[k]=merge(t[k<<1],t[k<<1|1]);}
     77 void pushdown(int k)
     78 {
     79     if(t[k].l==t[k].r)return;
     80     if(t[k].c!=-1)
     81     {
     82         t[k<<1].c=t[k<<1|1].c=t[k].c;
     83         color(k<<1,t[k].c);color(k<<1|1,t[k].c);
     84         t[k].c=-1;
     85     }
     86     if(t[k].rev)
     87     {
     88         t[k<<1].rev^=1;
     89         t[k<<1|1].rev^=1;
     90         rev(k<<1);rev(k<<1|1);
     91         t[k].rev=0;
     92     }        
     93 }
     94 void build(int k,int l,int r)
     95 {
     96     t[k].l=l;t[k].r=r;
     97     t[k].c=-1;
     98     if(l==r)
     99     {
    100         scanf("%d",&t[k].full);
    101         if(t[k].full)
    102         {t[k].l1=t[k].r1=t[k].m1=t[k].s1=1;}
    103         else
    104         {t[k].l0=t[k].r0=t[k].m0=t[k].s0=1;}
    105         return;
    106     }
    107     int mid=(l+r)>>1;
    108     build(k<<1,l,mid);build(k<<1|1,mid+1,r);
    109     pushup(k);
    110 }
    111 void change(int k,int x,int y,int v)
    112 {
    113     pushdown(k);
    114     int l=t[k].l,r=t[k].r;
    115     if(l==x && r==y)
    116     {
    117         color(k,v);
    118         t[k].c=v;
    119         return;
    120     }
    121     int mid=(l+r)>>1;
    122     if(mid>=y)change(k<<1,x,y,v);
    123     else if(mid<x)change(k<<1|1,x,y,v);
    124     else
    125     {
    126         change(k<<1,x,mid,v);
    127         change(k<<1|1,mid+1,y,v);
    128     }
    129     pushup(k);
    130 }
    131 void reverse(int k,int x,int y)
    132 {
    133     pushdown(k);
    134     int l=t[k].l,r=t[k].r;
    135     if(l==x && r==y)
    136     {
    137         rev(k);
    138         t[k].rev=1;
    139         return;
    140     }
    141     int mid=(l+r)>>1;
    142     if(mid>=y)reverse(k<<1,x,y);
    143     else if(mid<x)reverse(k<<1|1,x,y);
    144     else
    145     {
    146         reverse(k<<1,x,mid);
    147         reverse(k<<1|1,mid+1,y);
    148     }
    149     pushup(k);
    150 }
    151 seg ask(int k,int x,int y)
    152 {
    153     pushdown(k);
    154     int l=t[k].l,r=t[k].r;
    155     if(l==x && r==y)return t[k];
    156     int mid=(l+r)>>1;
    157     if(mid>=y)return ask(k<<1,x,y);
    158     else if(mid<x)return ask(k<<1|1,x,y);
    159     else return merge(ask(k<<1,x,mid),ask(k<<1|1,mid+1,y));
    160 }
    161 int asksum(int k,int x,int y)
    162 {
    163     pushdown(k);
    164     int l=t[k].l,r=t[k].r;
    165     if(l==x && r==y)return t[k].s1;
    166     int mid=(l+r)>>1;
    167     if(mid>=y)return asksum(k<<1,x,y);
    168     else if(mid<x)return asksum(k<<1|1,x,y);
    169     else return asksum(k<<1,x,mid)+asksum(k<<1|1,mid+1,y);
    170 }
    171 int main()
    172 {
    173     scanf("%d%d",&n,&m);
    174     build(1,1,n);
    175     for(int i=0;i<m;i++)
    176     {
    177         int f,x,y;
    178         scanf("%d%d%d",&f,&x,&y);
    179         x++;y++;
    180         if(f==0)change(1,x,y,0);
    181         if(f==1)change(1,x,y,1);
    182         if(f==2)reverse(1,x,y);
    183         if(f==3)printf("%d
    ",asksum(1,x,y));
    184         if(f==4)printf("%d
    ",ask(1,x,y).m1);
    185     }
    186 //    system("pause");
    187     return 0;
    188 }
  • 相关阅读:
    DBImport v3.44 中文版发布:数据库数据互导及文档生成工具(IT人员必备)
    IT人生知识分享:博弈论的理性思维
    IT人生知识分享:概率与运气
    开源:秋式广告杀手源码
    浅说秋色园域名被国家互联网应急中心封与解的过程
    自定义可视化调试工具(Microsoft.VisualStudio.DebuggerVisualizers)
    Excel导入导出的业务进化场景及组件化的设计方案(上)
    回忆录:30岁那年,你成长了吗?(上篇)
    Excel导入导出组件的设计
    DBImport v3.3 中文版发布:数据库数据互导及文档生成工具(IT人员必备)
  • 原文地址:https://www.cnblogs.com/fdfzhyf/p/6415288.html
Copyright © 2011-2022 走看看