CodeForces 339D Xenia and Bit Operations (线段树)
2024-08-28 13:24:13
题意:给定 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;
}
最新文章
- block,inline和inlinke-block细节对比
- 百度地图API 定位一直4.9E-324
- python 代码片段25
- Hibernate不调用update却自动更新
- 身份证号码15位转18位 C#实现
- 使用git和github托管个人项目
- PHP, Python Nginx works together!
- Linux Shell——函数的使用
- 51 Nod 1791 合法括号子段【分治+字符串】
- vue js实现获取两个日期之间所有日期
- 辗转相除法(GCD)求左旋转字符串
- 手动安装mysql
- Web轻量级扫描工具Skipfish
- Python 数据结构--查找
- windows分区
- linux之CentOS7在线安装Mysql
- Metasploit拿Shell
- c++ 替换修改一个文件夹下的所有文件的文件名
- redis未授权访问漏洞那拿SHELL
- POJ1163 数学三角求最大路径
热门文章
- Java复习——网络编程
- 请描述一下 cookies,sessionStorage和localStorage的区别?
- 比XGBOOST更快--LightGBM介绍
- [js方法pk]之instanceof() vs isPrototypeOf() hasOwnProperty() vs propertyIsEnumerable()
- 【转】javascript 执行环境,变量对象,作用域链
- SqlServer之geometry格式数据的添加和修改
- CentOS Grub、BASH 故障、解决方法
- a different object with the same identifier value was already associated with the session解决方案
- pl/sql中if语句的使用
- Python的常见异常处理