bzoj 1582 [Usaco2009 Hol]Holiday Painting 节日画画
1582: [Usaco2009 Hol]Holiday Painting 节日画画
Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 132 Solved: 72
[Submit][Status][Discuss]
Description
Input
第1行输入R,C,Q.接下来输入R行C列的目标画.之后Q行一行输入一次操作的5个参数.
Output
对每一次操作,输出操作过后正确着色的方格数.
Sample Input
17 15 10
111111101111111
111111000111111
111110000011111
111100000001111
111000000000111
111100000001111
111000000000111
110000000000011
111000000000111
110000000000011
100000000000001
110000000000011
100000000000001
000000000000000
111111000111111
111111000111111
111111000111111
5 8 2 14 1
8 17 3 7 1
4 5 10 15 0
7 16 12 14 1
2 17 13 14 0
2 6 2 3 1
13 14 4 8 1
3 6 6 7 1
1 16 10 11 0
7 16 10 10 0
111111101111111
111111000111111
111110000011111
111100000001111
111000000000111
111100000001111
111000000000111
110000000000011
111000000000111
110000000000011
100000000000001
110000000000011
100000000000001
000000000000000
111111000111111
111111000111111
111111000111111
5 8 2 14 1
8 17 3 7 1
4 5 10 15 0
7 16 12 14 1
2 17 13 14 0
2 6 2 3 1
13 14 4 8 1
3 6 6 7 1
1 16 10 11 0
7 16 10 10 0
Sample Output
113
94
95
91
87
93
91
87
93
93
94
95
91
87
93
91
87
93
93
思路: 由于最多只有15行,所以我们可以建立最多15个线段树,对每个线段树做染色,用tg表示这个段区间的颜色,用sum表示这段区间符合要求的有几个。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define mid (l+r)/2 4 #define lc (x<<1) 5 #define rc (x<<1|1) 6 int const N=50000+10; 7 int R,C,Q,cnt[N][17]; 8 char s[N][17]; 9 struct SegT{ 10 int tg[N<<2],sum[N<<2]; 11 void build(int x,int l,int r,int id){ 12 tg[x]=0; 13 if(l==r){ 14 if(s[r][id]=='0') sum[x]=1; 15 else sum[x]=0; 16 return; 17 } 18 build(lc,l,mid,id); 19 build(rc,mid+1,r,id); 20 sum[x]=sum[lc]+sum[rc]; 21 } 22 void pushdown(int x,int l,int r,int id){ 23 tg[lc]=tg[rc]=tg[x]; 24 int t=cnt[mid][id]-cnt[l-1][id]; 25 if(tg[lc]==1) sum[lc]=t; 26 else sum[lc]=mid-l+1-t; 27 t=cnt[r][id]-cnt[mid][id]; 28 if(tg[rc]==1) sum[rc]=t; 29 else sum[rc]=r-mid-t; 30 tg[x]=-1; 31 } 32 void update(int x,int l,int r,int ll,int rr,int v,int id){ 33 if(ll<=l && r<=rr) { 34 tg[x]=v; 35 int t=cnt[r][id]-cnt[l-1][id]; 36 if(v==1) sum[x]=t; 37 else sum[x]=r-l+1-t; 38 return ; 39 } 40 if(tg[x]>-1) pushdown(x,l,r,id); 41 if(ll<=mid) update(lc,l,mid,ll,rr,v,id); 42 if(rr>mid) update(rc,mid+1,r,ll,rr,v,id); 43 sum[x]=sum[lc]+sum[rc]; 44 } 45 }sg[16]; 46 47 int main(){ 48 scanf("%d%d%d",&R,&C,&Q); 49 for(int i=1;i<=R;i++) 50 scanf("%s",s[i]+1); 51 for(int i=1;i<=R;i++) 52 for(int j=1;j<=C;j++) 53 cnt[i][j]=cnt[i-1][j]+(s[i][j]=='1'); 54 for(int i=1;i<=C;i++) 55 sg[i].build(1,1,R,i); 56 int ans=0; 57 for(int i=1;i<=C;i++) 58 ans+=sg[i].sum[1]; 59 while (Q--){ 60 int x1,y1,x2,y2,z; 61 scanf("%d%d%d%d%d",&x1,&x2,&y1,&y2,&z); 62 for(int i=y1;i<=y2;i++) 63 sg[i].update(1,1,R,x1,x2,z,i); 64 int ans=0; 65 for(int i=1;i<=C;i++) 66 ans+=sg[i].sum[1]; 67 printf("%d\n",ans); 68 } 69 return 0; 70 }