poj 2155 matrix 二维线段树 线段树套线段树
题意
一个n∗n矩阵,初始全为0,每次翻转一个子矩阵,然后单点查找
题解
任意一种能维护二维平面的数据结构都可以
我这里写的是二维线段树,
因为四分树的写法复杂度可能会退化,因此考虑用树套树实现二维线段树
简单来说就是每个点都维护了一颗线段树...
因为二维线段树难以实现pushdown,而他的查找又是单点的
于是具体思路类似标记永久化,记录经过的点上的修改次数,最后判断修改次数的奇偶性即可
//为什么不写构造函数和vector?
//因为这是神奇的poj...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | #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; } } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步