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
    “这些年我一直提醒自己一件事情,千万不要自己感动自己。大部分人看似的努力,不过是愚蠢导致的。什么熬夜看书到天亮,连续几天只睡几小时,多久没放假了,如果这些东西也值得夸耀,那么富士康流水线上任何一个人都比你努力多了。人难免天生有自怜的情绪,唯有时刻保持清醒,才能看清真正的价值在哪里。”
  • 相关阅读:
    I.MX6 Surfaceflinger 机制
    理解 Android Fragment
    RPi 2B DDNS 动态域名
    RPi 2B IPC webcam server
    理解 Android MVP 开发模式
    I.MX6 system.img unpack repack
    can't set android permissions
    VMware Ubuntu 共享文件夹
    解决oracle数据库连接不上的问题
    perfect-scrollbar示例
  • 原文地址:https://www.cnblogs.com/Blogggggg/p/7137533.html
Copyright © 2011-2022 走看看