题意:给定 2的 n 次方个数,对这些数两个两个的进行或运算,然后会减少一半的数,然后再进行异或运算,又少了一半,然后再进行或运算,再进行异或,不断重复,到最后只剩下一个数,要输出这个数,然后有 m 个询问,

每个询问有 p 和 b,要求把第 p 个数改成 b,再这样运算,输出结果。

析:这个题是不是很像线段树,不过这个题不是随机询问哪个区间,区间是固定的,这样也就简单了很多,就省下了一个query函数,再就是线段树是从上到下的,所以我们要分好到底是异或还是或,然后就很简单了,

其实这个题也可以这样想,也是先构造一棵树,然后再考虑从下到上进行变,因为要改变值,所以先把最下面的改掉,然后再更新上去,这样次数比线段树少,比它更快一点,其实原理也是一样的。

代码如下:

线段树:

#include <bits/stdc++.h>
#define lson l,m,rt<<1,!ok
#define rson m+1,r,rt<<1|1,!ok using namespace std;
const int maxn = (1 << 17) + 5;
int sum[maxn<<2]; void pushup(int rt, bool ok){
if(ok) sum[rt] = sum[rt<<1] | sum[rt<<1|1];
else sum[rt] = sum[rt<<1] ^ sum[rt<<1|1];
} void build(int l, int r, int rt, bool ok){
if(l == r){
scanf("%d", &sum[rt]);
return ;
}
int m = (l+r) >> 1;
build(lson);
build(rson);
pushup(rt, ok);
} void update(int p, int b, int l, int r, int rt, bool ok){
if(l == r){
sum[rt] = b;
return ;
}
int m = (l+r) >> 1;
if(p <= m) update(p, b, lson);
else update(p, b, rson);
pushup(rt, ok);
} int main(){
int num, mm;
cin >> num >> mm;
int n = (1 << num);
bool ok = (num & 1);
build(1, n, 1, ok);
while(mm--){
int p, b;
scanf("%d %d", &p, &b);
update(p, b, 1, n, 1, ok);
printf("%d\n", sum[1]);
}
return 0;
}

另一种:

#include <bits/stdc++.h>

using namespace std;
const int maxn = (1 << 18) + 5;
int a[maxn];
int num; int main(){
int n, m;
cin >> n >> m;
num = 1 << n;
for(int i = 0; i < num; ++i) scanf("%d", &a[i+num]);//构造一棵树
int cnt = 0;
int t = num;
while(t){//把所有的值算一下
t >>= 1;
for(int i = 0; i < t; ++i)
if(cnt & 1) a[t+i] = a[(t+i)<<1] ^ a[(t+i)<<1|1];
else a[t+i] = a[(t+i)<<1] | a[(t+i)<<1|1];
++cnt;//控制是或还是异或
} while(m--){
int p, b;
scanf("%d %d", &p, &b);
cnt = 0; p += num-1;
a[p] = b;
while(p){//从下到上更新
p >>= 1;
if(cnt & 1) a[p] = a[p<<1] ^ a[p<<1|1];
else a[p] = a[p<<1] | a[p<<1|1];
++cnt;
} printf("%d\n", a[1]);
}
return 0;
}

最新文章

  1. block,inline和inlinke-block细节对比
  2. 百度地图API 定位一直4.9E-324
  3. python 代码片段25
  4. Hibernate不调用update却自动更新
  5. 身份证号码15位转18位 C#实现
  6. 使用git和github托管个人项目
  7. PHP, Python Nginx works together!
  8. Linux Shell——函数的使用
  9. 51 Nod 1791 合法括号子段【分治+字符串】
  10. vue js实现获取两个日期之间所有日期
  11. 辗转相除法(GCD)求左旋转字符串
  12. 手动安装mysql
  13. Web轻量级扫描工具Skipfish
  14. Python 数据结构--查找
  15. windows分区
  16. linux之CentOS7在线安装Mysql
  17. Metasploit拿Shell
  18. c++ 替换修改一个文件夹下的所有文件的文件名
  19. redis未授权访问漏洞那拿SHELL
  20. POJ1163 数学三角求最大路径

热门文章

  1. Java复习——网络编程
  2. 请描述一下 cookies,sessionStorage和localStorage的区别?
  3. 比XGBOOST更快--LightGBM介绍
  4. [js方法pk]之instanceof() vs isPrototypeOf() hasOwnProperty() vs propertyIsEnumerable()
  5. 【转】javascript 执行环境,变量对象,作用域链
  6. SqlServer之geometry格式数据的添加和修改
  7. CentOS Grub、BASH 故障、解决方法
  8. a different object with the same identifier value was already associated with the session解决方案
  9. pl/sql中if语句的使用
  10. Python的常见异常处理