zoukankan      html  css  js  c++  java
  • POJ3225

    题目链接:https://vjudge.net/problem/POJ-3225

    解题思路:这道题要是不看题解以本渣新现在的实力确实是做不出来。
      以区间为基础建立线段树。
      当X=‘U', 将区间T内的线段上的数字都置为1;当X='I', 将区间T外面的数字置为0;当X=‘D‘,将区间T内的数字置为0;当X=‘C',将区间T外的数字置为0,区间T内的数字0/1倒置;当X=‘S',将区间T内的数字0/1倒置。这就是整道题的精髓所在。

      在AC代码中,lazy标记的使用值得细细品味,对于0/1倒置这种操作,如果对同一区间使用偶数次,那么就相当于没有操作,于是用lazy先给有这种操作的区间做好标记,用PushDown()函数保证在每次线段树更新到这个区间之前,0/1倒置的操作已经完成,lazy标志清0。PushDown()也算是一个重点吧,因为这个而WA了好几发。本来还有一个PushUp()函数的,但是对于这种类型的线段树,PushUp()其实有点行不通。

    AC代码:

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <algorithm>
      4 using namespace std;
      5 const int maxn=131072;
      6 const int inf=131072;
      7 int tree[maxn<<2];
      8 int lazy[maxn<<2];
      9 int ans[maxn+1];
     10 void PushDown(int rt){
     11     if(tree[rt]!=-1){
     12         tree[rt<<1|1]=tree[rt<<1]=tree[rt];
     13         lazy[rt<<1|1]=lazy[rt<<1]=0;
     14     }
     15     if(lazy[rt]){
     16         if(tree[rt<<1]!=-1)
     17             tree[rt<<1]^=1;
     18         else
     19             lazy[rt<<1]^=1;
     20         if(tree[rt<<1|1]!=-1)
     21             tree[rt<<1|1]^=1;
     22         else
     23             lazy[rt<<1|1]^=1;
     24         lazy[rt]=0;
     25     }
     26     tree[rt]=-1;
     27 }
     28 void change(int L,int R,int l,int r,int rt){
     29     if(L<=l&&r<=R){
     30         if(tree[rt]!=-1)
     31             tree[rt]^=1;
     32         else
     33             lazy[rt]^=1;
     34         return;
     35     }
     36     if(l==r)
     37         return;
     38     PushDown(rt);
     39     int m=(l+r)>>1;
     40     if(L<=m)    change(L,R,l,m,rt<<1);
     41     if(R>m)     change(L,R,m+1,r,rt<<1|1);
     42 }
     43 void update(int L,int R,int c,int l,int r,int rt){
     44     if(L<=l&&r<=R){
     45         tree[rt]=c;
     46         lazy[rt]=0;
     47         return;
     48     }
     49     if(l==r)
     50         return;
     51     PushDown(rt);
     52     int m=(l+r)>>1;
     53     if(L<=m)    update(L,R,c,l,m,rt<<1);
     54     if(R>m)     update(L,R,c,m+1,r,rt<<1|1);
     55 }
     56 void query(int l,int r,int rt){
     57     if(tree[rt]==1){
     58         if(lazy[rt]){
     59             tree[rt]=0;
     60             lazy[rt]=0;
     61             return;
     62         }
     63         for(int i=l;i<=r;i++){
     64             ans[i]=tree[rt];
     65         }
     66         return;
     67     }
     68     if(tree[rt]==0)    return;
     69     if(l==r){
     70         return;
     71     }
     72     PushDown(rt);
     73     int m=(l+r)>>1;
     74     query(l,m,rt<<1);
     75     query(m+1,r,rt<<1|1);
     76 }
     77 int main(){
     78     char in1[5],in2[20];
     79     while(scanf("%s %s",in1,in2)==2){
     80         int x,y;
     81         sscanf(&in2[1],"%d",&x);
     82         sscanf(strstr(in2,",")+1,"%d",&y);
     83         x=x*2;      y=y*2;
     84         if(in2[0]=='(') x++;
     85         if(strstr(in2,")")!=NULL)   y--;
     86 
     87         if(x>y){
     88             if(in1[0]=='I'||in1[0]=='C'){
     89                 lazy[1]=tree[1]=0;
     90             }
     91         }
     92         else{
     93             if(in1[0]=='U')     update(x,y,1,0,inf,1);
     94             else if(in1[0]=='I'){
     95                 update(0,x-1,0,0,inf,1);
     96                 update(y+1,inf,0,0,inf,1);
     97             }
     98             else if(in1[0]=='D')
     99                 update(x,y,0,0,inf,1);
    100             else if(in1[0]=='C'){
    101                 change(x,y,0,inf,1);
    102                 update(0,x-1,0,0,inf,1);
    103                 update(y+1,inf,0,0,inf,1);
    104             }
    105             else
    106                 change(x,y,0,inf,1);
    107         }
    108     }
    109     query(0,inf,1);
    110     int flag=0;
    111     int ind=0;
    112     for(int i=0;i<=inf;i++){
    113         if(!flag&&ans[i]){
    114             if(ind)
    115                 printf(" ");
    116             if(i%2)
    117                 printf("(");
    118             else
    119                 printf("[");
    120             printf("%d,",i/2);
    121             ind++;
    122             flag=1;
    123         }
    124         else if(flag&&!ans[i]){
    125             printf("%d",i/2);
    126             if((i-1)%2)
    127                 printf(")");
    128             else
    129                 printf("]");
    130             flag=0;
    131         }
    132     }
    133     if(!ind)    printf("empty set");
    134     printf("
    ");
    135     return 0;
    136 }
    View Code
    “这些年我一直提醒自己一件事情,千万不要自己感动自己。大部分人看似的努力,不过是愚蠢导致的。什么熬夜看书到天亮,连续几天只睡几小时,多久没放假了,如果这些东西也值得夸耀,那么富士康流水线上任何一个人都比你努力多了。人难免天生有自怜的情绪,唯有时刻保持清醒,才能看清真正的价值在哪里。”
  • 相关阅读:
    前缀和
    B. Ilya and Queries
    BZOJ1652 [Usaco2006 Feb]Treats for the Cows
    NOIP2014提高组 酱油记
    NOIP初赛 BLESS ALL!
    BZOJ1096 [ZJOI2007]仓库建设
    BZOJ1036 [ZJOI2008]树的统计Count
    BZOJ1030 [JSOI2007]文本生成器
    BZOJ2749 [HAOI2012]外星人
    BZOJ1093 [ZJOI2007]最大半连通子图
  • 原文地址:https://www.cnblogs.com/Blogggggg/p/7137533.html
Copyright © 2011-2022 走看看