FZU 2105 Digits Count(按位维护线段树)
【题目链接】 http://acm.fzu.edu.cn/problem.php?pid=2105
【题目大意】
给出一个序列,数字均小于16,为正数,每次区间操作可以使得
1. [l,r]区间and一个数
2. [l,r]区间or一个数
3. [l,r]区间xor一个数
4. [l,r]区间查询和
操作数均为小于16的非负整数
【题解】
由于操作数很小,因此我们可以按位维护四棵线段树,表示二进制中的第i位,
对于and操作,只有当and的当前位为0时才对区间有影响,效果是将区间全部变为0,
对于or和xor操作,当前位为1的时候才对区间有影响,
因为and和or是全区间变化为同一个值,因此区间和会变为全区间或者0,
那么and和or的变化只需要看父区间的值来决定子区间的变化而不需要标记传递
对于xor操作,相当于区间01翻转,用一个标记记录翻转次数即可,
【代码】
#include <cstdio>
#include <algorithm>
using namespace std;
const int N=1000010;
int T[4][N<<2],tag[4][N<<2],a[N];
void up(int k,int x){T[k][x]=T[k][x<<1]+T[k][x<<1|1];}
void pb(int k,int x,int l,int r){
int mid=(l+r)>>1;
if(T[k][x]==r-l+1){T[k][x<<1]=mid-l+1;T[k][x<<1|1]=r-mid;}
if(!T[k][x]){T[k][x<<1]=T[k][x<<1|1]=0;}
if(tag[k][x]){
tag[k][x]^=1;
if(T[k][x]!=r-l+1&&T[k][x]){
T[k][x<<1]=mid-l+1-T[k][x<<1];
T[k][x<<1|1]=r-mid-T[k][x<<1|1];
}tag[k][x<<1]^=1;tag[k][x<<1|1]^=1;
}
}
void build(int k,int x,int l,int r){
int mid=(l+r)>>1;
tag[k][x]=0;
if(l==r){T[k][x]=(a[l]>>k)&1;return;}
build(k,x<<1,l,mid);build(k,x<<1|1,mid+1,r);
up(k,x);
}
void update(int k,int x,int l,int r,int L,int R,char op){
int mid=(l+r)>>1;
if(L<=l&&r<=R){
if(op=='A')T[k][x]=0;
if(op=='O')T[k][x]=r-l+1;
if(op=='X')T[k][x]=(r-l+1)-T[k][x],tag[k][x]^=1;
return;
}pb(k,x,l,r);
if(L<=mid)update(k,x<<1,l,mid,L,R,op);
if(mid+1<=R)update(k,x<<1|1,mid+1,r,L,R,op);
up(k,x);
}
int query(int k,int x,int l,int r,int L,int R){
int mid=(l+r)>>1;
if(L<=l&&r<=R)return T[k][x]; pb(k,x,l,r);
int res=0;
if(L<=mid)res+=query(k,x<<1,l,mid,L,R);
if(mid+1<=R)res+=query(k,x<<1|1,mid+1,r,L,R);
return res;
}
int Cas,n,m;
char op[10];
int main(){
scanf("%d",&Cas);
while(Cas--){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
for(int i=0;i<4;i++)build(i,1,1,n);
while(m--){
scanf("%s",op);
if(op[0]=='S'){
int l,r,ans=0;
scanf("%d%d",&l,&r);
l++;r++;
for(int i=0;i<4;i++)ans+=query(i,1,1,n,l,r)*(1<<i);
printf("%d\n",ans);
}else{
int l,r,x;
scanf("%d%d%d",&x,&l,&r); l++,r++;
for(int i=0;i<4;i++)if((op[0]=='A')^((x>>i)&1))update(i,1,1,n,l,r,op[0]);
}
}
}return 0;
}
FZU 2105 Digits Count(按位维护线段树)的更多相关文章
- ACM: FZU 2105 Digits Count - 位运算的线段树【黑科技福利】
FZU 2105 Digits Count Time Limit:10000MS Memory Limit:262144KB 64bit IO Format:%I64d & ...
- FZU 2105 Digits Count(线段树)
Problem 2105 Digits Count Accept: 302 Submit: 1477 Time Limit: 10000 mSec Memory Limit : 262144 KB P ...
- FZU 2105 Digits Count
Problem 2105 Digits Count Accept: 444 Submit: 2139 Time Limit: 10000 mSec Memory Limit : 2621 ...
- FZU 2105 Digits Count(位数计算)
Description 题目描述 Given N integers A={A[0],A[1],...,A[N-1]}. Here we have some operations: Operation ...
- fzu 2105 Digits Count ( 线段树 ) from 第三届福建省大学生程序设计竞赛
http://acm.fzu.edu.cn/problem.php?pid=2105 Problem Description Given N integers A={A[0],A[1],...,A[N ...
- FZU2105 Digits Count(按位建线段树)题解
题意: 给出区间与.或.异或\(x\)操作,还有询问区间和. 思路: 因为数比较小,我们给每一位建线段树,这样每次只要更新对应位的答案. 与\(0\)和或\(1\)相当于重置区间,异或\(1\)相当于 ...
- 【GDKOI2016Day1T1-魔卡少女】【拆位】线段树维护区间内所有连续子区间的异或和
题意:给出N个数,M个操作.操作有修改和询问两种,每次修改将一个数改成另一个数,每次询问一个区间的所有连续子区间的异或和.n,m<=100000,ai<=1000 题解: 当年(其实也就是 ...
- FOJ 2105 Digits Count
题意:对一串数字进行抑或某数,和某数,或某数,统计某区间和的操作. 思路:因为化成二进制就4位可以建4颗线段树,每颗代表一位二进制. and 如果该为是1 直接无视,是0则成段赋值为0: or 如 ...
- HDU 6155 Subsequence Count(矩阵乘法+线段树+基础DP)
题意 给定一个长度为 \(n\) 的 \(01\) 串,完成 \(m\) 种操作--操作分两种翻转 \([l,r]\) 区间中的元素.求区间 \([l,r]\) 有多少个不同的子序列. \(1 \le ...
随机推荐
- RabbitMq related
# RabbitMq related Integration of message queuing tools with systems is the usual solution to handle ...
- Fermat2018游记
day (-22) 2018年2月5日 Devin大佬给我发了一份Waterloo AIF的原件截图,发现里面居然直接问你的Fermat分数,那么这么重要的考试当然不能错过啊 若干天之后刚开学不久的一 ...
- CCC2018游记
day (-1) 晚上睡觉没盖被子 day 0 2018年2月13日 下午放学回来感到一阵头痛,一量体温结果发烧了,感觉很蓝瘦,居然在CCC前一天生病. 本来注册了账号想打practise的,结果又 ...
- vue清空input file
input file是只读的,给form一个id,用form.reset()干掉里面input的值 document.getElementById("uploadForm")&am ...
- Sketch VS Photoshop
参考:http://mp.weixin.qq.com/s?__biz=MjM5NTQ5MjIyMA==&mid=217309554&idx=4&sn=4d6a5239ca813 ...
- hdu 2962 Trucking (二分+最短路Spfa)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2962 Trucking Time Limit: 20000/10000 MS (Java/Others ...
- selenium在爬虫领域的初涉(自动打开网站爬取信息)
selenium简介 Selenium 是一个用于Web应用程序测试的工具.Selenium测试直接运行在浏览器中,就像真正的用户在操作一样.这个工具的主要功能包括:测试与浏览器的兼容性--测试你的应 ...
- [device tree] interrupt mapping example
This is for Devicetree Specification Release 0.1 Interrupt Mapping Example p19 在講解前,先帶進一些 PCI 的基礎觀念 ...
- python基础===解决python3 UnicodeEncodeError: 'gbk' codec can't encode character '\xXX' in position XX(转载)
本文转自:解决python3 UnicodeEncodeError: 'gbk' codec can't encode character '\xXX' in position XX 从网上抓了一些字 ...
- webview loadRequest
// 所构建的NSURLRequest具有一个依赖于缓存响应的特定策略,cachePolicy取得策略,timeoutInterval取得超时值 [self.yourSite loadRequest: ...