SPOJ IITWPC4F - Gopu and the Grid Problem (双线段树区间修改 区间查询)
Posted 贱人方
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SPOJ IITWPC4F - Gopu and the Grid Problem (双线段树区间修改 区间查询)相关的知识,希望对你有一定的参考价值。
Gopu and the Grid Problem
Gopu is interested in the integer co-ordinates of the X-Y plane (0<=x,y<=100000). Each integer coordinate contain a lamp, initially all the lamps are in off mode. Flipping a lamp means switching it on if it is in off mode and vice versa. Maggu will ask gopu 3 type of queries.
Type 1: x l r, meaning: flip all the lamps whose x-coordinate are between l and r (both inclusive) irrespective of the y coordinate.
Type 2: y l r, meaning: flip all the lamps whose y-coordinate are between l and r (both inclusive) irrespective of the x coordinate.
Type 3: q x y X Y, meaning: count the number of lamps which are in ‘on mode’(say this number be A) and ‘off mode’ (say this number be B) in the region where x-coordinate is between x and X(both inclusive) and y-coordinate is between y and Y(both inclusive).
Input
First line contains Q-number of queries that maggu will ask to gopu. (Q <= 10^5)
Then there will be Q lines each containing a query of one of the three type described above.
Output
For each query of 3rd type you need to output a line containing one integer A.
Example
Input:
3
x 0 1
y 1 2
q 0 0 2 2
Output:
4
一开始想的是直接二维线段树或者二维树状数组搞一下,然后一看数据范围,GG。实在没办法看了网上的题解,用两个线段树分别处理行和列,然后查询的时候,再综合一下。
减去重叠的部分。
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include <cmath> #include <string> #include <map> #include <stack> #include <queue> #include <vector> #define inf 0x3f3f3f3f #define met(a,b) memset(a,b,sizeof a) #define pb push_back typedef long long ll; using namespace std; const int N = 1e5+5; const int M = 24005; typedef long long LL; int q; struct Seg { int Tree[N << 2]; // 标记的行数/列数 bool lazy[N << 2]; void init() { memset(Tree, 0, sizeof(Tree)); memset(lazy, 0, sizeof(lazy)); } inline void pushup(int rt) { Tree[rt] = Tree[rt << 1] + Tree[rt << 1 | 1]; } inline void pushdown(int pos,int len) { if(lazy[pos]) { Tree[pos<<1]=len-len/2-Tree[pos<<1]; Tree[pos<<1|1]=len/2-Tree[pos<<1|1]; lazy[pos<<1]^=1; lazy[pos<<1|1]^=1; lazy[pos]=0; } return; } void update(int L,int R,int l,int r,int pos) { if(l>=L&&r<=R) { Tree[pos]=(r-l+1)-Tree[pos]; lazy[pos]^=1; return; } int mid=(l+r)>>1; pushdown(pos,r-l+1); if(L<=mid) update(L,R,l,mid,pos<<1); if(mid<R)update(L,R,mid+1,r,pos<<1|1); pushup(pos); } int query(int L,int R,int l,int r,int pos) { if(L<=l&&r<=R)return Tree[pos]; int mid=(l+r)>>1; pushdown(pos,r-l+1); int ans=0; if(L<=mid) ans+=query(L,R,l,mid,pos<<1); if(R>mid) ans+=query(L,R,mid+1,r,pos<<1|1); return ans; } }row,col; int main() { char op[5]; int n = N; row.init(); col.init(); int l,r,val; int lx,ly,rx,ry; char sign[20]; int m; scanf("%d",&m); while(m--) { scanf("%s",sign); if(sign[0]==‘x‘) { scanf("%d%d",&l,&r); ++l,++r; row.update(l,r,1,n,1); } else if(sign[0]==‘y‘){ scanf("%d%d",&l,&r); ++l,++r; col.update(l,r,1,n,1); } else { scanf("%d%d%d%d",&lx,&ly,&rx,&ry); ++lx,++ly,++rx,++ry; int nx=row.query(lx,rx,1,n,1); int ny=col.query(ly,ry,1,n,1); ll ans=(ll)(rx-lx+1)*ny+(ll)(ry-ly+1)*nx-(ll)2*nx*ny; printf("%lld\n",ans); } } }
以上是关于SPOJ IITWPC4F - Gopu and the Grid Problem (双线段树区间修改 区间查询)的主要内容,如果未能解决你的问题,请参考以下文章
SPOJSPCQ - Gopu and Digits Divisibility 数位处理
SPOJ:Lost and survived(multiset+并查集)
SPOJ:Ada and Orange Tree (LCA+Bitset)
SPOJ:Bits. Exponents and Gcd(组合数+GCD)