[bzoj1582][Usaco2009 Hol]Holiday Painting 节日画画_线段树
生活随笔
收集整理的這篇文章主要介紹了
[bzoj1582][Usaco2009 Hol]Holiday Painting 节日画画_线段树
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
Holiday Painting 節(jié)日畫畫 bzoj-1582 Usaco-2009 Hol
題目大意:給定兩個n*m的01網(wǎng)格圖。q次操作,每次將第二個網(wǎng)格圖的子矩陣全部變成0或1,問每一次操作后兩個網(wǎng)格圖有多少個格子不一樣。
注釋:$1\le n\le 5\cdot 10^4$,$1\le m\le 15$,$1\le q\le 10^4$。
想法:由于網(wǎng)格圖的列比較少,很容易想到對每行建立一棵線段樹。
然后就是線段樹上維護的東西:我們考慮直接維護成對應區(qū)間中有多少不一樣的格子數(shù)。
這個屬性顯然滿足可加性。修改怎么辦?
修改的時候就是再處理出第一個網(wǎng)格圖的區(qū)間0的個數(shù)。如果賦成0信息就變成區(qū)間長度減去0的個數(shù),如果是1信息就是區(qū)間0的個數(shù)。
最后,附上丑陋的代碼... ...
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 50001
#define root 1,1,n
#define ls now<<1,l,mid
#define rs now<<1|1,mid+1,rint n,m,q,res;
int ans[16][N<<2],sum[16][N][2],add[16][N<<2];
char s[N];
inline char nc() {static char *p1,*p2,buf[100000]; return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;}
int rd() {int x=0; char c=nc(); while(!isdigit(c)) c=nc(); while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=nc(); return x;}
void build(int id,int now,int l,int r)
{if(l==r){ans[id][now]=sum[id][l][0]-sum[id][l-1][0];return;}int mid=(l+r)>>1;build(id,ls);build(id,rs);ans[id][now]=ans[id][now<<1]+ans[id][now<<1|1];
}inline void pushdown(int id,int now,int l,int r)
{if(add[id][now]^-1){int mid=(l+r)>>1;add[id][now<<1]=add[id][now];add[id][now<<1|1]=add[id][now];ans[id][now<<1]=sum[id][mid][add[id][now]]-sum[id][l-1][add[id][now]];ans[id][now<<1|1]=sum[id][r][add[id][now]]-sum[id][mid][add[id][now]];add[id][now]=-1;}
}
inline void update(int id,int now,int l,int r,int x,int y,int c)
{if(x<=l&&r<=y){add[id][now]=c;ans[id][now]=sum[id][r][c]-sum[id][l-1][c];return;}pushdown(id,now,l,r);int mid=(l+r)>>1;if(x<=mid) update(id,ls,x,y,c);if(mid<y) update(id,rs,x,y,c);ans[id][now]=ans[id][now<<1]+ans[id][now<<1|1];
}
int main()
{int i,j,r1,r2,c1,c2,x;n=rd(),m=rd(),q=rd();for(i=1;i<=n;i++){scanf("%s",s+1);for(j=1;j<=m;j++){sum[j][i][0]=sum[j][i-1][0]+(s[j]=='0');sum[j][i][1]=sum[j][i-1][1]+(s[j]=='1');}}for(i=1;i<=m;i++)build(i,root);memset(add,-1,sizeof(add));while(q--){r1=rd(),r2=rd(),c1=rd(),c2=rd();x=rd();res=0;for(i=c1;i<=c2;i++)update(i,root,r1,r2,x);for(i=1;i<=m;i++)res+=ans[i][1];printf("%d\n",res);}return 0;
}
小結(jié):線段樹使用起來是極其靈活的哦。
轉(zhuǎn)載于:https://www.cnblogs.com/ShuraK/p/9675240.html
總結(jié)
以上是生活随笔為你收集整理的[bzoj1582][Usaco2009 Hol]Holiday Painting 节日画画_线段树的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 吹膜机,制袋机,冲口机,印刷机,一套多少
- 下一篇: 几个圆圈是谁画的啊?