poj 2155 matrix 二維線段樹 線段樹套線段樹
阿新 • • 發佈:2019-01-09
題意
一個$n*n$矩陣,初始全為0,每次翻轉一個子矩陣,然後單點查詢
題解
任意一種能維護二維平面的資料結構都可以
我這裡寫的是二維線段樹,
因為四分樹的寫法複雜度可能會退化,因此考慮用樹套樹實現二維線段樹
簡單來說就是每個點都維護了一顆線段樹...
因為二維線段樹難以實現pushdown,而他的查詢又是單點的
於是具體思路類似標記永久化,記錄經過的點上的修改次數,最後判斷修改次數的奇偶性即可
//為什麼不寫建構函式和vector?
//因為這是神奇的poj...
#include<iostream> #include<string> #include<vector> #include<string.h> #define endl '\n' #define ll long long #define ull unsigned long long #define fi first #define se second #define mp make_pair #define pii pair<int,int> #define all(x) x.begin(),x.end() #define IO ios::sync_with_stdio(false) #define rep(ii,a,b) for(int ii=a;ii<=b;++ii) #define per(ii,a,b) for(int ii=b;ii>=a;--ii) #define forn(ii,x) for(int ii=head[x];ii;ii=e[ii].next) using namespace std; const int maxn=4e3+10,maxm=2e6+10; const ll INF=0x3f3f3f3f3f3f3f3f; const int mod=1e9+7; int casn,n,m,k,d; class sstree{ #define nd node[nowx][nowy] public: struct segnode {int val;}; // vector<vector<segnode> > node; int n,m,x1,x2,y1,y2,x,nowx; int ans; segnode node[maxn][maxn]; void init(int nn,int mm) { n=nn,m=mm; memset(node ,0,sizeof node); // node.resize(n*4+10); // rep(i,0,(n*4+9)) node[i].resize(m*4+10); } void update(int xx1,int xx2,int yy1,int yy2){ x1=xx1,y1=yy1,x2=xx2,y2=yy2; updatex(1,n); } void updatey(int l,int r,int nowy=1){ if(y1>r||y2<l) return ; if(y1<=l&&y2>=r){nd.val^=1;return ;} updatey(l,(l+r)>>1,nowy<<1); updatey(((l+r)>>1)+1,r,nowy<<1|1); } void updatex(int l,int r,int now=1){ if(x1>r||x2<l) return ; if(x1<=l&&x2>=r) {nowx=now;updatey(1,m);return ;} updatex(l,(l+r)>>1,now<<1); updatex(((l+r)>>1)+1,r,now<<1|1); } int query(int xx,int yy){ x1=xx,y1=yy;ans=0; queryx(1,n); return ans; } void queryy(int l,int r,int nowy=1){ if(y1>r||y1<l) return ; ans^=nd.val; if(l==r) return ; queryy(l,(l+r)>>1,nowy<<1);queryy(((l+r)>>1)+1,r,nowy<<1|1); } void queryx(int l,int r,int now=1){ if(x1>r||x1<l) return ; nowx=now;queryy(1,m); if(l==r) return ; queryx(l,(l+r)>>1,now<<1);queryx(((l+r)>>1)+1,r,now<<1|1); } }tree; int main() { IO; cin>>casn; register int a,b,c,d; string s; while(casn--){ cin>>n>>m; tree.init(n,n); while(m--){ cin>>s; if(s[0]=='C') { cin>>a>>b>>c>>d; tree.update(a,c,b,d); }else { cin>>a>>b; cout<<tree.query(a,b)<<endl; } } if(casn) cout<<endl; } }