• MZOJ #83 位运算


    分析

    关于位运算

    位运算,不同位之间互不影响,于是有同学是一位一位来的

    其实一般遇到了位运算的题都可以考虑一位一位操作

    然鹅有大佬炸空间了

    不过也有大佬过了

    我倒是没有一位一位存,不过思想是一样的,

    关于 & 操作

    关于&操作的结果,是把原来的1变成了0,其余位不改变

    也就是说,这个&操作,相当于0的or操作

    关于change值

    对于&的change值,如果change的这一位是1,那么这一位的答案不影响,如果这一位是0,那么区间所有数的这一位都变成了0

    而 | 操作恰恰相反,

    对于|的change值,如果change的这一位是0,那么这一位的答案不影响,如果这一位是1,那么区间所有数的这一位都变成了1

    区间奇偶讨论

    因为&操作是赋零,0的异或值一定是0所以不分奇偶讨论

    因为|操作是赋一,1的异或值与奇偶有关,所以区间的异或值与区间长度的奇偶性有关

    关于lazytag

    某一位是0或1与区间长度的奇偶性有关,与父亲区间长无关,所以从父亲继承lazytag的时候保留原来的的值

    又因为lazytag之间操作会相互影响,所以也要互相标记

    关于题解

    代码

      1 /********************
      2 User:Mandy
      3 Language:c++
      4 Problem:
      5 ********************/
      6 //关于&操作的结果,是把原来的1变成了0,其余位不改变
      7 //也就是说,这个&操作,相当于0的or操作,
      8 //对于change,如果change的这一位是1,那么这一位的答案不影响,如果这一位是0,那么区间所有数的这一位都变成了0 
      9 //|操作恰恰相反,
     10 // 对于change,如果change的这一位是0,那么这一位的答案不影响,如果这一位是1,那么区间所有数的这一位都变成了1
     11 //接下来就是奇偶讨论了
     12 //about lazytag:与区间长度的奇偶性有关,与父亲区间长无关,所以从父亲继承的时候保留原来的的值 
     13 //&操作因为是赋零,0的异或值一定是0所以不分奇偶讨论 
     14 #include<bits/stdc++.h>
     15 #define lson l,mid,k<<1
     16 #define rson mid + 1,r,k<<1|1
     17 
     18 using namespace std;
     19 
     20 const int maxn = 2e5 + 5;
     21 
     22 int n,m,change;
     23 bool K[20]; 
     24 int tree[maxn << 2];
     25 int  lazy[maxn << 2][3];
     26 //lazy[k][0] -> & 
     27 //lazy[k][1] -> | 
     28 char *TT,*mo,but[(1 << 15) + 2];
     29 #define getchar() ((TT == mo && (mo = ((TT = but) + fread(but,1,1 << 15,stdin)),TT == mo)) ? -1 : *TT++) 
     30 template<class T>inline void read(T &x){
     31     x = 0;bool flag = 0;char ch = getchar();
     32     while(!isdigit(ch)) flag |= ch == '-',ch = getchar();
     33     while(isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48),ch = getchar();
     34     if(flag) x = -x;
     35 }
     36 
     37 template<class T>void putch(const T x){
     38     if(x > 9) putch(x / 10);
     39     putchar(x % 10 | 48);
     40 }
     41 
     42 template<class T>void put(const T x){
     43     if(x < 0) putchar('-'),putch(-x);
     44     else putch(x);
     45 }
     46 
     47 void file(){
     48     freopen("bit8.in","r",stdin);
     49     freopen("bit.out","w",stdout);
     50 }
     51 
     52 void pushup(int k){
     53     tree[k] = tree[k<<1]^tree[k<<1|1];
     54 }
     55 
     56 void buildtree(int l,int r,int k){
     57     lazy[k][0] = (1 << 30)-1;//初值!!! 
     58     if(l == r){
     59         read(tree[k]);
     60         return;
     61     }
     62     int mid = (l + r) >> 1;
     63     buildtree(lson);
     64     buildtree(rson);
     65     pushup(k);
     66 }
     67 
     68 void readdata(){
     69     read(n);read(m);
     70     buildtree(1,n,1);
     71 }
     72 
     73 void pushdown(int l,int r,int k){
     74     int mid = (l+r)>>1;
     75     int ls = k<<1;
     76     int rs = k<<1|1;
     77     tree[ls] &= lazy[k][0];
     78     tree[rs] &= lazy[k][0];
     79     
     80     lazy[ls][0] &= lazy[k][0];
     81     lazy[rs][0] &= lazy[k][0];
     82     lazy[ls][1] &= lazy[k][0];
     83     lazy[rs][1] &= lazy[k][0];
     84     lazy[ls][1] |= lazy[k][1];
     85     lazy[ls][0] |= lazy[k][1];
     86     lazy[rs][1] |= lazy[k][1];
     87     lazy[rs][0] |= lazy[k][1];
     88     //about lazytag:与区间长度的奇偶性有关,与父亲区间长无关,所以从父亲继承的时候保留原来的的值
     89     if((mid-l+1)&1) tree[ls] |= lazy[k][1];
     90     else tree[ls] &= (((1 << 30)-1) ^ lazy[k][1]);
     91     
     92     if((r - mid) & 1) tree[rs] |= lazy[k][1];    
     93     else tree[rs] &= (((1 << 30)-1) ^ lazy[k][1]);    
     94     
     95     lazy[k][0] = (1 << 30)-1;
     96     lazy[k][1] = 0;
     97 }
     98 
     99 void And(int l,int r,int k,int x,int y){
    100     if(x <= l && r <= y){
    101         tree[k] &= change;
    102         lazy[k][0] &= change;
    103         lazy[k][1] &= change;
    104         //&操作因为是赋零,0的异或值一定是0所以不分奇偶讨论 
    105         //因为lazytag之间操作会相互影响,所以也要互相标记
    106         return;
    107     }
    108     pushdown(l,r,k);
    109     int mid = (l + r) >> 1;
    110     if(x <= mid) And(lson,x,y);
    111     if(y > mid) And(rson,x,y);
    112     pushup(k);
    113 }
    114 
    115 void Or(int l,int r,int k,int x,int y){
    116     if(x <= l && r <= y){
    117         if((r-l+1)&1) tree[k] |= change;
    118         else tree[k] &= (((1 << 30)-1) ^change);
    119         
    120         lazy[k][1] |= change;
    121         lazy[k][0] |= change;
    122         return;
    123     }
    124     pushdown(l,r,k);
    125     int mid = (l + r) >> 1;
    126     if(x <= mid) Or(lson,x,y);
    127     if(y > mid) Or(rson,x,y);
    128     pushup(k);
    129 }
    130 
    131 int  query(int l,int r,int k,int x,int y){
    132     if(x <= l && r <= y) return tree[k];
    133     pushdown(l,r,k);
    134     int mid = (l + r) >> 1;
    135     int ans = 0;
    136     if(x <= mid) ans ^= query(lson,x,y);
    137     if(y > mid) ans^= query(rson,x,y);    
    138     return ans;
    139 }
    140 
    141 void work(){
    142     while(m--){
    143         int opt,k,l,r;        
    144         read(opt);
    145         
    146         switch(opt){//opt possible != 1 or 2 or 3
    147             case 1:{
    148                 read(l);read(r);
    149                 read(change);
    150                 And(1,n,1,l,r);
    151                 break;
    152             }
    153             case 2:{read(l);read(r);
    154                 read(change);
    155                 Or(1,n,1,l,r);
    156                 break;
    157             }
    158             case 3:{read(l);read(r);
    159                 int ans = query(1,n,1,l,r);
    160                 put(ans);
    161                 puts("");
    162                 break;
    163             }
    164             default:{
    165                 break;
    166             }
    167         }
    168     }
    169 }
    170 
    171 int main(){
    172 //    file();
    173     readdata();
    174     work();
    175     return 0;
    176 }
    不拆位
      1 #include<bits/stdc++.h>
      2 #define re return
      3 #define inc(i,l,r) for(register int i=l;i<=r;++i)
      4 using namespace std;
      5 template<typename T>inline void rd(T&x)
      6 {
      7     char c;bool f=0;
      8     while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
      9     x=c^48;
     10     while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
     11 }
     12 
     13 const int maxn=1000005;
     14 int n,m,K[20],a,ans[20];
     15 
     16 bool tr[maxn][20];
     17 int lazy[maxn][20];
     18 //tr原数,lazy懒标记 
     19 
     20 #define lson rt<<1
     21 #define rson rt<<1|1
     22 
     23 inline void pushup(int rt)
     24 {
     25     inc(i,0,19)
     26     tr[rt][i]=tr[lson][i]^tr[rson][i];
     27 }
     28 
     29 inline void build(int rt,int l,int r)
     30 {
     31     if(l==r)
     32     {
     33         rd(a);
     34         inc(i,0,19)
     35         tr[rt][i]=(a>>i)&1;
     36         re ;
     37     }
     38     
     39     int mid=(l+r)>>1;
     40     build(lson,l,mid);
     41     build(rson,mid+1,r);
     42     pushup(rt);
     43 }
     44 
     45 inline void pushdown(int rt,int l,int r,int mid)
     46 {
     47     inc(i,0,19)
     48     if(lazy[rt][i])
     49     {
     50         lazy[lson][i]=lazy[rson][i]=lazy[rt][i];
     51         if(lazy[rt][i]==1)
     52             tr[lson][i]=tr[rson][i]=0;
     53         else 
     54         {
     55             tr[lson][i]=(mid-l+1)&1;
     56             tr[rson][i]=(r-mid)&1;
     57         }
     58         lazy[rt][i]=0;
     59     }
     60 
     61 }
     62 
     63 inline void modify_and(int rt,int l,int r,int x,int y)
     64 {
     65     if(x<=l&&r<=y)
     66     {
     67         inc(i,0,19)
     68         if(!K[i])
     69         {
     70             tr[rt][i]=0;
     71             lazy[rt][i]=1;//区间赋0 
     72         }
     73         re ;
     74     }
     75     int mid=(l+r)>>1;
     76     pushdown(rt,l,r,mid);
     77     if(x<=mid)modify_and(lson,l,mid,x,y);
     78     if(y>mid)modify_and(rson,mid+1,r,x,y);
     79     
     80     pushup(rt);
     81 }
     82 
     83 inline void modify_or(int rt,int l,int r,int x,int y)
     84 {
     85     if(x<=l&&r<=y)
     86     {
     87         int f=(r-l+1)&1;
     88         inc(i,0,19)
     89         if(K[i])
     90         {
     91             tr[rt][i]=f;
     92             lazy[rt][i]=2;//区间赋1 
     93         }
     94         re ;
     95     }
     96     int mid=(l+r)>>1;
     97     pushdown(rt,l,r,mid);
     98     if(x<=mid)modify_or(lson,l,mid,x,y);
     99     if(y>mid)modify_or(rson,mid+1,r,x,y);
    100     
    101     pushup(rt);
    102 }
    103 
    104 inline void ask(int rt,int l,int r,int x,int y)
    105 {
    106     if(x<=l&&r<=y)
    107     {
    108         inc(i,0,19)
    109         ans[i]^=tr[rt][i];
    110         re ;
    111     }
    112     int mid=(l+r)>>1;
    113     pushdown(rt,l,r,mid);
    114     if(x<=mid)ask(lson,l,mid,x,y);
    115     if(y>mid) ask(rson,mid+1,r,x,y);
    116 }
    117 
    118 int main()
    119 {
    120     //freopen("in.txt","r",stdin);
    121     rd(n),rd(m);
    122     build(1,1,n);
    123     
    124     int opt,k,l,r,ansnow;
    125     inc(i,1,m)
    126     {
    127         rd(opt);
    128         if(opt==3)
    129         {    
    130         rd(l),rd(r);
    131             ansnow=0;
    132             ask(1,1,n,l,r);
    133             inc(j,0,17)
    134             if(ans[j])
    135             {
    136                 ansnow|=(1<<j);
    137                 ans[j]=0;
    138             }
    139             printf("%d
    ",ansnow);
    140         
    141         }
    142         else if(opt==1||opt==2)
    143         {
    144             
    145         rd(l),rd(r);
    146             rd(k);
    147             inc(j,0,17)
    148             K[j]=(k>>j)&1;
    149             if(opt==1)modify_and(1,1,n,l,r);    
    150             else modify_or(1,1,n,l,r);
    151         }
    152     
    153     }
    154     re 0;
    155 }
    拆位 By LSY
  • 相关阅读:
    跟我学习编写通用的单据编码生成器
    asp.net MVC 框架中控制器里使用Newtonsoft.Json对前端传过来的字符串进行解析
    c#语言中的Process进程类型的使用示例
    C#语言中的XmlSerializer类的XmlSerializer.Deserialize (Stream)方法举例详解
    C#语言中的XmlSerializer类的XmlSerializer.Serialize(Stream,Object)方法举例详解
    大型三甲医院管理系统源码PACS超声科室源码DICOM影像工作站
    大型EMR电子病历源码三甲医院医疗信息管理系统软件网络版
    大型三甲医院信息管理系统源码 His系统功能齐全 完整可用
    大型三甲医院医疗体检信息管理系统源码 PEIS 体检科软件 CS
    大型进销存管理系统源码 家电业 电器类进销存 asp.net C#框架
  • 原文地址:https://www.cnblogs.com/Mandy-H-Y/p/11479126.html
Copyright © 2020-2023  润新知