xor or and 线段树
2024-10-07 06:29:18
每一位维护一颗线段树
(-1)^1 =-2
(-2)^1=-1
#include <cstdio>
#include<iostream>
using namespace std;
//#define int long long
#define si signed
#define sc(x) scanf("%d", &x);
#define P pair<int, int>
int lazy[][];
int sum[][];
int A[];
int n, m;
void pushdown(int id, int x, int l, int r)
{
if (lazy[id][x] == )
{
lazy[id][x] = ;
int mid = l + r >> ;
lazy[id][x << ] ^= ;
sum[id][x << ] = (mid - l + ) - sum[id][x << ];
lazy[id][x << | ] ^= ;
sum[id][x << | ] = (r - mid) - sum[id][x << | ];
}
else if (lazy[id][x] == -)
{
lazy[id][x] = ;
int mid = l + r >> ;
lazy[id][x << ] = -;
sum[id][x << ] = (mid - l + );
lazy[id][x << | ] = -;
sum[id][x << | ] = (r - mid);
}
else if (lazy[id][x] == -)
{
lazy[id][x] = ;
int mid = l + r >> ;
lazy[id][x << ] = -;
sum[id][x << ] = ;
lazy[id][x << | ] = -;
sum[id][x << | ] = ;
}
}
void pushup(int id, int x)
{
sum[id][x] = sum[id][x << ] + sum[id][x << | ];
}
void build(int id, int l, int r, int x)
{
lazy[id][x] = ;
if (l == r)
{
sum[id][x] = ((A[l] >> id) & );
return;
}
int mid = (l + r) / ;
build(id, l, mid, x << );
build(id, mid + , r, x << | );
pushup(id, x);
}
void update(int id, int l, int r, int x, int type, int L, int R)
{
if (type == )
{
// cout<<type<<"type"<<endl; if (l >= L && r <= R)
{
lazy[id][x] ^= ;
sum[id][x] = (r - l + ) - sum[id][x];
//cout<<L<<' '<<R<<endl;
return;
}
pushdown(id, x, l, r);
int mid = (l + r) >> ;
if (L <= mid)
update(id, l, mid, x << , type, L, R);
if (R > mid)
update(id, mid + , r, x << | , type, L, R);
pushup(id, x);
}
else if (type == )
{ if (l >= L && r <= R)
{
lazy[id][x] = -;
sum[id][x] = ;
return;
}
pushdown(id, x, l, r);
int mid = (l + r) >> ;
if (L <= mid)
update(id, l, mid, x << , type, L, R);
if (R > mid)
update(id, mid + , r, x << | , type, L, R);
pushup(id, x);
}
else
{ if (l >= L && r <= R)
{
lazy[id][x] = -;
sum[id][x] = r - l + ;
return;
}
pushdown(id, x, l, r);
int mid = (l + r) >> ;
if (L <= mid)
update(id, l, mid, x << , type, L, R);
if (R > mid)
update(id, mid + , r, x << | , type, L, R);
pushup(id, x);
}
}
int query(int id, int l, int r, int x, int L, int R)
{
int ans = ;
if (L <= l && r <= R)
{
return sum[id][x];
}
pushdown(id, x, l, r);
int mid = l + r >> ;
if (L <= mid)
ans += query(id, l, mid, x << , L, R);
if (R > mid)
ans += query(id, mid + , r, x << | , L, R);
return ans;
}
si main()
{
int T;
sc(T)
string s;
while (T--)
{
sc(n) sc(m);
for (int i = ; i <= n; i++)
sc(A[i])
for (int i = ; i <; i++)
{
build(i, , n-, );
} int l,r,x;
while (m--)
{
cin >> s;
if (s[] == 'S')
{
sc(l) sc(r)
int ans=;
for(int i=;i<;i++){
ans +=query(i,,n-,,l,r)*(<<i);
}
cout<<ans<<'\n';
}
else if (s[] == 'X')
{
sc(x)
sc(l) sc(r) for(int i=;i<;i++){
if((x>>i)&){
update(i,,n-,,,l,r);
}
}
}
else if (s[] == 'O')
{
sc(x)
sc(l) sc(r) for(int i=;i<;i++){
if((x>>i)&){
update(i,,n-,,,l,r);
}
}
}
else
{
sc(x)
sc(l) sc(r) for(int i=;i<;i++){
if(!((x>>i)&)){
update(i,,n-,,,l,r);
}
}
}
}
} //system("pause");
}
最新文章
- makefile之变量赋值
- shell 除法 小数点
- 基于服务(Web Service)的文件管理Winform程序实现
- JS原生第二篇 (帅哥)
- C#复习①
- HTML文档中头部文件介绍
- C++中 destory() 和deallocate()以及delete函数的相关性和区别性
- demo05
- SQL中补0
- ruby的gem和boundle安装解决办法
- java Future 模式
- c++虚函数的学习
- SQL Server 中的跨库视图
- 将博客搬至CSDN https://blog.csdn.net/Fredric_2014
- Java安全编码:糟糕的在线建议和令人困惑的APIs
- (二 -3) 天猫精灵接入Home Assistant-自动发现Mqtt设备--灯系列
- JavaWeb - Servlet教程
- 一分钟学会ConstraintLayout(转载)
- hive 字段名称显示
- OpencvSharp 在WPF的Image控件中显示图像