题目链接

给n个数, 两种操作, 一种是求区间内的数的和, 一种是将区间内的数异或x。

异或x没有什么思路, 单个异或肯定超时, 区间异或也没有办法做....后来才知道可以按位建线段树, 这样建20棵线段树就可以。

每一次异或, 对于给定的x, 如果x的第i位是1, 那么就将第i棵线段树在给定的区间内0,1翻转, 这是很基础的操作。

对于区间求和操作, 我们可以求出给定的区间, 从高位到低位, 每一位依次有多少个1, 然后就可以直接求出来, 感觉不好表达....具体看代码。

 #include<bits/stdc++.h>
using namespace std;
#define pb(x) push_back(x)
#define ll long long
#define mk(x, y) make_pair(x, y)
#define lson l, m, rt<<1
#define mem(a) memset(a, 0, sizeof(a))
#define rson m+1, r, rt<<1|1
#define mem1(a) memset(a, -1, sizeof(a))
#define mem2(a) memset(a, 0x3f, sizeof(a))
#define rep(i, a, n) for(int i = a; i<n; i++)
#define ull unsigned long long
typedef pair<int, int> pll;
const double PI = acos(-1.0);
const double eps = 1e-;
const int mod = 1e9+;
const int inf = ;
const int dir[][] = { {-, }, {, }, {, -}, {, } };
const int maxn = 1e5+;
int sum[maxn<<][], XOR[maxn<<][], a[];
void pushUp(int rt, int pos) {
sum[rt][pos] = sum[rt<<][pos] + sum[rt<<|][pos];
}
void pushDown(int rt, int m, int pos) {
if(XOR[rt][pos]) {
sum[rt<<][pos] = (m-(m>>)) - sum[rt<<][pos];
sum[rt<<|][pos] = (m>>)-sum[rt<<|][pos];
XOR[rt<<][pos] ^= ;
XOR[rt<<|][pos] ^= ;
XOR[rt][pos] = ;
}
}
void update(int L, int R, int l, int r, int rt, int pos) {
if(L<=l&&R>=r) {
XOR[rt][pos] ^= ;
sum[rt][pos] = r-l+-sum[rt][pos];
return ;
}
pushDown(rt, r-l+, pos);
int m = l+r>>;
if(L<=m)
update(L, R, lson, pos);
if(R>m)
update(L, R, rson, pos);
pushUp(rt, pos);
}
int query(int L, int R, int l, int r, int rt, int pos) {
if(L<=l&&R>=r) {
return sum[rt][pos];
}
pushDown(rt, r-l+, pos);
int m = l+r>>, ret = ;
if(L<=m)
ret += query(L, R, lson, pos);
if(R>m)
ret += query(L, R, rson, pos);
return ret;
}
int main()
{
int n, x, m, y, sign, z;
cin>>n;
mem(XOR);
for(int i = ; i<=n; i++) {
scanf("%d", &x);
for(int j = ; j<; j++) {
if((<<j)&x) {
update(i, i, , n, , j);
}
}
}
cin>>m;
while(m--) {
scanf("%d", &sign);
if(sign==) {
ll tmp = ;
scanf("%d%d", &x, &y);
for(int i = ; i>=; i--) {
tmp = 1ll*tmp*+query(x, y, , n, , i); //query是求这个区间里每一位有多少个1
}
cout<<tmp<<endl;
} else {
scanf("%d%d%d", &x, &y, &z);
for(int j = ; j<; j++) {
if(z&(<<j)) { //如果给出的x第j位是1, 那么就将区间内第j棵线段树翻转
update(x, y, , n, , j);
}
}
}
}
return ;
}

codeforces 242E. XOR on Segment 线段树的更多相关文章

  1. codeforces 22E XOR on Segment 线段树

    题目链接: http://codeforces.com/problemset/problem/242/E E. XOR on Segment time limit per test 4 seconds ...

  2. codeforces 242E - XOR on Segment (线段树 按位数建树)

    E. XOR on Segment time limit per test 4 seconds memory limit per test 256 megabytes input standard i ...

  3. CodeForces 242E - XOR on Segment 二维线段树?

    今天练习赛的题....又是线段树的变换..拿到题我就敲了个点更新区间查询的..果断超时...然后想到了可以将每个数与合表示成不进位的二进制数..这样就可以区间进行更新了..比赛的时候写搓了..刚重写了 ...

  4. CodeForces 242E "XOR on Segment"(线段树)

    传送门 •题意 给你一个包含 n 个数的序列 a,定义序列上的两个操作: (1)$1,l,r\ :\ ans=\sum_{i=l}^{r}a_i$; (2)$2,l,r,x\ :\ \forall\ ...

  5. Codeforces Round #149 (Div. 2) E. XOR on Segment (线段树成段更新+二进制)

    题目链接:http://codeforces.com/problemset/problem/242/E 给你n个数,m个操作,操作1是查询l到r之间的和,操作2是将l到r之间的每个数xor与x. 这题 ...

  6. XOR on segment(线段树区间异或更新)

    原题传送门 本题大意:给定n个数字和m个操作,操作共有两种,第一种是求解区间l到r上元素的和,第二种是将区间l到r的元素都异或一个x,作为某个位置的新值. 很容易想到线段树维护区间和,但是我们发现,在 ...

  7. codeforces Good bye 2016 E 线段树维护dp区间合并

    codeforces Good bye 2016 E 线段树维护dp区间合并 题目大意:给你一个字符串,范围为‘0’~'9',定义一个ugly的串,即串中的子串不能有2016,但是一定要有2017,问 ...

  8. luogu P2574 XOR的艺术 (线段树)

    luogu P2574 XOR的艺术 (线段树) 算是比较简单的线段树. 当区间修改时.\(1 xor 1 = 0,0 xor 1 = 1\)所以就是区间元素个数减去以前的\(1\)的个数就是现在\( ...

  9. CodeForces 516C Drazil and Park 线段树

    原文链接http://www.cnblogs.com/zhouzhendong/p/8990745.html 题目传送门 - CodeForces 516C 题意 在一个环上,有$n$棵树. 给出每一 ...

随机推荐

  1. C#核编之一个简单的C#程序

    构建一个简单的C#应用程序需要注意一下几点: 1.C#要求所有的程序逻辑都包含在一个类型定义中       --->这里的类型指的是(类,接口,结构,枚举,委托中的一个或多个) 2.与其他语言不 ...

  2. Java学习之Java中常用对象

    java的几种对象(PO,VO,DAO,BO,POJO)解释     一.PO:persistant object 持久对象,可以看成是与数据库中的表相映射的java对象.最简单的PO就是对应数据库中 ...

  3. 独立版Jexus

    一:下载资源包 把 jexus压缩包下载到linux临时文件夹中. cd /tmp wget linuxdot.net/down/jexus--x64.tar.gz 二,解压: tar -zxvf j ...

  4. Android padding和margin的区别

    如: Padding 为内边框,指该控件内部内容,如文本/图片距离该控件的边距 Margin 为外边框,指该控件距离边父控件的边距 如: 当按钮分别设置以上两个属性时,得到的效果是不一样的. andr ...

  5. hadoop笔记之Hive的数据存储(桶表)

    Hive的数据存储(桶表) Hive的数据存储(桶表) 桶表 桶表是对数据进行哈希取值,然后放到不同文件中存储. 比如说,创建三个桶,而创建桶的原则可以按照左边表中学生的名字来创建对应的桶.这样子把左 ...

  6. php composer包管理工具

    一 . 包管理工具 你在Centos上装工具的时候直接yum -y install xx 比你去rpm -ivh xx.rpm 是不是爽很多呢? composer 就是安装php 代码的一个类似工具. ...

  7. Header() in PHP &html – Refresh (Redirect) to Location (URL) in X seconds

    Case 1 : Redirect a page to a URL without waiting in PHP. 1 header("Location: index.php"); ...

  8. IOSJSBRIGE商品内容模板

    <p> 内容 </p> <script> window.onerror = function(err) { log('window.onerror: ' + err ...

  9. C语言入门(11)——switch分支语句

    C语言提供了一种用于多分支选择的switch语句, 其一般形式为: switch(表达式) { case 常量表达式1:语句1; break; case 常量表达式2:语句2; break; .... ...

  10. WebService-06-CXF与Spring集成

    前言 自3月份到一家快递公司之后,就极少有时间来写博客了,进去的第一个周末就加班.做公司的开放平台,协助一个小伙伴写WebService接口,用的就是CXF.正好这个东西曾经使用过.如今快7月了,曾经 ...