逃票的chanming(1)
2014-04-25 21:33
405 查看
Description
这是一个神奇的国度。这个国度一共有N个城市组成,让我们将他们编号为1~N,
这一天,chanming带着他的第一个月的工资K元来到了城市1。他想到城市N去寻找宝藏。qinhang3想跟chanming一起去,但是chanming并不想带他(太大只,逃票太明显)。于是他对qinhang3说,这样吧,你帮我解决这个问题,我们就一起走,不然就只能友尽了,这个题目是这样的:
有一个长度为N的序列,初始值都为0。
现在有2种不同操作:
操作0: 读入p,q,v,并且a[p] ^= v, a[p + 1] ^= v, .. ,a[q] ^= v;
操作1: 读入p,q,输出s = a[p] ^ a[p + 1] ^ a[p + 2]..^a[q]的结果;
*@.@*...还好qinhang3找到了一位神犇帮忙,不用东张西望了,就是你!如果你能解决这个问题的话,qinhang3将送给你一个精美的气球作为报答。
Input
单组数据第一行为两个数N,M,分别表示序列的个数和操作的个数
接下来M行,第一个数op,表示操作的种类,如果为0,读入p,q,v,如果为1,读入p,q
N <= 500000
M <= 500000
0 < v < 2^30
Output
对于个op为1,输出结果。
Sample Input
100 30 2 6 30 1 2 71 2 3
Sample Output
7题意:区间异或某值,询问区间和。
思路:线段树维护区间异或值,懒惰标记区间异或某值。只用PushDown,不用PushUp。比赛的时候用结构体写的线段树
一直过不了、、、赛后用数组改写才AC~~~
#include <iostream> #include <cstdio> #include <cstring> using namespace std; #define lson (id<<1) #define rson (id<<1|1) #define maxn (500080<<2) #define mid ((ll+rr)>> 1) int sum[maxn],add[maxn]; int len(int ll,int rr) { return rr-ll+1; } void scanf_(int & num) { char in; while((in = getchar()) > '9' || in < '0'); num = in - '0'; while(in = getchar(),in >= '0' && in <= '9') num *= 10,num += in-'0'; } void PushDown(int id,int ll,int rr) { if(add[id]) { add[lson] ^= add[id]; add[rson] ^= add[id]; if(len(ll,mid)&1) sum[lson] ^= add[id]; if(len(mid+1,rr)&1) sum[rson] ^= add[id]; add[id] = 0; } } void update(int id,int ll,int rr,int l,int r,int v) { if(len(l,r)&1) sum[id] ^= v; if(ll == l && rr == r) { add[id] ^= v; return; } PushDown(id,ll,rr); if(r <= mid) update(lson,ll,mid,l,r,v); else if(l > mid) update(rson,mid+1,rr,l,r,v); else { update(lson,ll,mid,l,mid,v); update(rson,mid+1,rr,mid+1,r,v); } } int query(int id,int ll,int rr,int l,int r) { if(ll == l && rr == r) return sum[id]; PushDown(id,ll,rr); if(r <= mid) return query(lson,ll,mid,l,r); else if(l > mid) return query(rson,mid+1,rr,l,r); else return query(lson,ll,mid,l,mid)^query(rson,mid+1,rr,mid+1,r); } int main() { //freopen("in.txt","r",stdin); int n,m; scanf_(n);scanf_(m); while(m--) { int ope,l,r,v; //scanf("%d",&ope); scanf_(ope); if(ope == 1) { //scanf("%d%d",&l,&r); scanf_(l); scanf_(r); printf("%d\n",query(1,1,n,l,r)); } else { //scanf("%d%d%d",&l,&r,&v); scanf_(l); scanf_(r); scanf_(v); update(1,1,n,l,r,v); } } return 0; }
比赛时的TLE版本:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <map> #include <set> #include <stack> using namespace std; #define min(a,b) a > b?b:a; #define max(a,b) a > b?a:b; #define lson id<<1,l,mid #define rson id<<1|1,mid+1,r #define LL long long int #define maxn 1000080 void scanf_(int & num) { char in; while((in = getchar()) > '9' || in < '0'); num = in - '0'; while(in = getchar(),in >= '0' && in <= '9') num *= 10,num += in-'0'; } struct ST { int l,r,set,sum,fuck; }st[maxn<<2]; void buildtree(int id,int l,int r) { st[id].l = l ,st[id].r = r; st[id].set = 0; if((r-l+1)&1) st[id].fuck = 1; else st[id].fuck = 0; st[id].sum = 0; if(l == r) { return; } int mid = (l+r) >> 1; buildtree(lson); buildtree(rson); } /* void PushUp(int id) { st[id].sum = st[id<<1].sum ^ st[id<<1|1].sum; } */ void PushDown(int id) { if(st[id].set) { if(!st[id<<1].set) st[id<<1].set = st[id].set; else st[id<<1].set ^= st[id].set; if(!st[id<<1|1].set) st[id<<1|1].set = st[id].set; else st[id<<1|1].set ^= st[id].set; if(st[id<<1].fuck) st[id<<1].sum ^= st[id].set; if(st[id<<1|1].fuck) st[id<<1|1].sum ^= st[id].set; st[id].set = 0; } } void Update(int id,int l,int r,int v) { if((r-l+1)&1) st[id].sum ^= v; if(st[id].l == l && st[id].r == r) { if(!st[id].set) { st[id].set = v; } else st[id].set ^= v; //if(st[id].fuck) st[id].sum ^= v; return; } PushDown(id); if(st[id<<1].r >= r) Update(id<<1,l,r,v); else if(st[id<<1|1].l <= l) Update(id<<1|1,l,r,v); else { Update(id<<1,l,st[id<<1].r,v); Update(id<<1|1,st[id<<1|1].l,r,v); } } int query(int id,int l,int r) { if(st[id].l == l && st[id]. r == r) return st[id].sum; PushDown(id); if(st[id<<1].r >= r) return query(id<<1,l,r); else if(st[id<<1|1].l <= l) return query(id<<1|1,l,r); return query(id<<1,l,st[id<<1].r)^(query(id<<1|1,st[id<<1|1].l,r)); } int main() { int n,m; //scanf_(n);scanf_(m); scanf("%d%d",&n,&m); buildtree(1,1,n); while(m--) { int ope,l,r,v; scanf("%d",&ope); //scanf_(ope); if(ope == 1) { scanf("%d%d",&l,&r); //scanf_(l); //scanf_(r); printf("%d\n",query(1,l,r)); } else { scanf("%d%d%d",&l,&r,&v); //scanf_(l); //scanf_(r); //scanf_(v); Update(1,l,r,v); } } return 0; }
相关文章推荐
- HDU 1048 The Hardest Problem Ever
- 今天是讲解struts框架实现的jsp页面的跳转
- poj 2387 Til the Cows Come Home spfa+dis解答
- 给节点设置tag【从零开始cocos3.0final 】
- 【jQuery】页面顶部显示的进度条效果
- 2013 通化邀请赛
- 新一周冲刺计划2
- C/C++每日小练(七)——墓地雕塑
- 线性表(二)
- DNS \ ARP 解析过程
- linux下通过命令行使用Vtune统计处理器微体系结构特征
- 大数据的排序问题
- 消息事件通知拓展点
- eclipse中package部分包变成了文件夹
- begin+1
- 基于人脸识别的程序自动管理软件
- Java面试题和答案
- 关于编程时的高质量
- tomcat详细日志配置
- 2013各大IT公司薪资待遇