【UVa】11992 Fast Matrix Operations

  1 #include<cstdio>

  2 #define INF 0x7FFFFFFF

  3 #define MAXN 1000010

  4 struct node

  5 {

  6     int cnt,son[4],kind[4];

  7     int big,small,sum,add,cover;

  8 };

  9 node tree[MAXN<<2];

 10 int size,SUM,BIG,SMALL;

 11 inline int MAX(int x,int y)

 12 {

 13     return x>y?x:y;

 14 }

 15 inline int MIN(int x,int y)

 16 {

 17     return x>y?y:x;

 18 }

 19 void Build(int x1,int x2,int y1,int y2,int rt)

 20 {

 21     tree[rt].cnt=0;

 22     tree[rt].big=tree[rt].small=tree[rt].sum=tree[rt].add=tree[rt].cover=0;

 23     if(x1!=x2||y1!=y2)

 24     {

 25         int i,mid1=(x1+x2)>>1,mid2=(y1+y2)>>1;

 26         if(x1<=mid1)

 27         {

 28             if(y1<=mid2)

 29             {

 30                 tree[rt].kind[tree[rt].cnt]=1;

 31                 tree[rt].son[tree[rt].cnt++]=size++;

 32             }

 33             if(y2>mid2)

 34             {

 35                 tree[rt].kind[tree[rt].cnt]=2;

 36                 tree[rt].son[tree[rt].cnt++]=size++;

 37             }

 38         }

 39         if(x2>mid1)

 40         {

 41             if(y1<=mid2)

 42             {

 43                 tree[rt].kind[tree[rt].cnt]=3;

 44                 tree[rt].son[tree[rt].cnt++]=size++;

 45             }

 46             if(y2>mid2)

 47             {

 48                 tree[rt].kind[tree[rt].cnt]=4;

 49                 tree[rt].son[tree[rt].cnt++]=size++;

 50             }

 51         }

 52         for(i=0;i<tree[rt].cnt;i++)

 53         {

 54             if(tree[rt].kind[i]==1)

 55                 Build(x1,mid1,y1,mid2,tree[rt].son[i]);

 56             else if(tree[rt].kind[i]==2)

 57                 Build(x1,mid1,mid2+1,y2,tree[rt].son[i]);

 58             else if(tree[rt].kind[i]==3)

 59                 Build(mid1+1,x2,y1,mid2,tree[rt].son[i]);

 60             else

 61                 Build(mid1+1,x2,mid2+1,y2,tree[rt].son[i]);

 62         }

 63     }

 64 }

 65 void PushDown(int x1,int x2,int mid1,int y1,int y2,int mid2,int rt)

 66 {

 67     int i;

 68     if(tree[rt].cover)

 69     {

 70         for(i=0;i<tree[rt].cnt;i++)

 71         {

 72             if(tree[rt].kind[i]==1)

 73                 tree[tree[rt].son[i]].sum=(mid1-x1+1)*(mid2-y1+1)*tree[rt].cover;

 74             else if(tree[rt].kind[i]==2)

 75                 tree[tree[rt].son[i]].sum=(mid1-x1+1)*(y2-mid2)*tree[rt].cover;

 76             else if(tree[rt].kind[i]==3)

 77                 tree[tree[rt].son[i]].sum=(x2-mid1)*(mid2-y1+1)*tree[rt].cover;

 78             else

 79                 tree[tree[rt].son[i]].sum=(x2-mid1)*(y2-mid2)*tree[rt].cover;

 80             tree[tree[rt].son[i]].add=0;

 81             tree[tree[rt].son[i]].cover=tree[tree[rt].son[i]].big=tree[tree[rt].son[i]].small=tree[rt].cover;

 82         }

 83         tree[rt].cover=0;

 84     }

 85     if(tree[rt].add)

 86     {

 87         for(i=0;i<tree[rt].cnt;i++)

 88         {

 89             if(tree[rt].kind[i]==1)

 90                 tree[tree[rt].son[i]].sum+=(mid1-x1+1)*(mid2-y1+1)*tree[rt].add;

 91             else if(tree[rt].kind[i]==2)

 92                 tree[tree[rt].son[i]].sum+=(mid1-x1+1)*(y2-mid2)*tree[rt].add;

 93             else if(tree[rt].kind[i]==3)

 94                 tree[tree[rt].son[i]].sum+=(x2-mid1)*(mid2-y1+1)*tree[rt].add;

 95             else

 96                 tree[tree[rt].son[i]].sum+=(x2-mid1)*(y2-mid2)*tree[rt].add;

 97             tree[tree[rt].son[i]].add+=tree[rt].add;

 98             tree[tree[rt].son[i]].big+=tree[rt].add;

 99             tree[tree[rt].son[i]].small+=tree[rt].add;

100         }

101         tree[rt].add=0;

102     }

103 }

104 void PushUp(int rt)

105 {

106     int i;

107     tree[rt].big=tree[rt].sum=0;

108     tree[rt].small=INF;

109     for(i=0;i<tree[rt].cnt;i++)

110     {

111         tree[rt].sum+=tree[tree[rt].son[i]].sum;

112         tree[rt].big=MAX(tree[rt].big,tree[tree[rt].son[i]].big);

113         tree[rt].small=MIN(tree[rt].small,tree[tree[rt].son[i]].small);

114     }

115 }

116 void Add(int x1,int x2,int y1,int y2,int val,int a,int b,int c,int d,int rt)

117 {

118     if(x1<=a&&b<=x2&&y1<=c&&d<=y2)

119     {

120         tree[rt].add+=val;

121         tree[rt].big+=val;

122         tree[rt].small+=val;

123         tree[rt].sum+=val*(b-a+1)*(d-c+1);

124     }

125     else

126     {

127         int mid1=(a+b)>>1,mid2=(c+d)>>1,i=0;

128         PushDown(a,b,mid1,c,d,mid2,rt);

129         if(x1<=mid1)

130         {

131             if(y1<=mid2)

132             {

133                 for(;tree[rt].kind[i]!=1&&i<tree[rt].cnt;i++);

134                 if(tree[rt].kind[i]==1)

135                     Add(x1,x2,y1,y2,val,a,mid1,c,mid2,tree[rt].son[i]);

136             }

137             if(y2>mid2)

138             {

139                 for(;tree[rt].kind[i]!=2&&i<tree[rt].cnt;i++);

140                 if(tree[rt].kind[i]==2)

141                     Add(x1,x2,y1,y2,val,a,mid1,mid2+1,d,tree[rt].son[i]);

142             }

143         }

144         if(x2>mid1)

145         {

146             if(y1<=mid2)

147             {

148                 for(;tree[rt].kind[i]!=3&&i<tree[rt].cnt;i++);

149                 if(tree[rt].kind[i]==3)

150                     Add(x1,x2,y1,y2,val,mid1+1,b,c,mid2,tree[rt].son[i]);

151             }

152             if(y2>mid2)

153             {

154                 for(;tree[rt].kind[i]!=4&&i<tree[rt].cnt;i++);

155                 if(tree[rt].kind[i]==4)

156                     Add(x1,x2,y1,y2,val,mid1+1,b,mid2+1,d,tree[rt].son[i]);

157             }

158         }

159         PushUp(rt);

160     }

161 }

162 void Cover(int x1,int x2,int y1,int y2,int val,int a,int b,int c,int d,int rt)

163 {

164     if(x1<=a&&b<=x2&&y1<=c&&d<=y2)

165     {

166         tree[rt].add=0;

167         tree[rt].cover=tree[rt].big=tree[rt].small=val;

168         tree[rt].sum=val*(b-a+1)*(d-c+1);

169     }

170     else

171     {

172         int mid1=(a+b)>>1,mid2=(c+d)>>1,i=0;

173         PushDown(a,b,mid1,c,d,mid2,rt);

174         if(x1<=mid1)

175         {

176             if(y1<=mid2)

177             {

178                 for(;tree[rt].kind[i]!=1&&i<tree[rt].cnt;i++);

179                 if(tree[rt].kind[i]==1)

180                     Cover(x1,x2,y1,y2,val,a,mid1,c,mid2,tree[rt].son[i]);

181             }

182             if(y2>mid2)

183             {

184                 for(;tree[rt].kind[i]!=2&&i<tree[rt].cnt;i++);

185                 if(tree[rt].kind[i]==2)

186                     Cover(x1,x2,y1,y2,val,a,mid1,mid2+1,d,tree[rt].son[i]);

187             }

188         }

189         if(x2>mid1)

190         {

191             if(y1<=mid2)

192             {

193                 for(;tree[rt].kind[i]!=3&&i<tree[rt].cnt;i++);

194                 if(tree[rt].kind[i]==3)

195                     Cover(x1,x2,y1,y2,val,mid1+1,b,c,mid2,tree[rt].son[i]);

196             }

197             if(y2>mid2)

198             {

199                 for(;tree[rt].kind[i]!=4&&i<tree[rt].cnt;i++);

200                 if(tree[rt].kind[i]==4)

201                     Cover(x1,x2,y1,y2,val,mid1+1,b,mid2+1,d,tree[rt].son[i]);

202             }

203         }

204         PushUp(rt);

205     }

206 }

207 void Query(int x1,int x2,int y1,int y2,int a,int b,int c,int d,int rt)

208 {

209     if(x1<=a&&b<=x2&&y1<=c&&d<=y2)

210     {

211         SUM+=tree[rt].sum;

212         BIG=MAX(BIG,tree[rt].big);

213         SMALL=MIN(SMALL,tree[rt].small);

214     }

215     else

216     {

217         int mid1=(a+b)>>1,mid2=(c+d)>>1,i=0;

218         PushDown(a,b,mid1,c,d,mid2,rt);

219         if(x1<=mid1)

220         {

221             if(y1<=mid2)

222             {

223                 for(;tree[rt].kind[i]!=1&&i<tree[rt].cnt;i++);

224                 if(tree[rt].kind[i]==1)

225                     Query(x1,x2,y1,y2,a,mid1,c,mid2,tree[rt].son[i]);

226             }

227             if(y2>mid2)

228             {

229                 for(;tree[rt].kind[i]!=2&&i<tree[rt].cnt;i++);

230                 if(tree[rt].kind[i]==2)

231                     Query(x1,x2,y1,y2,a,mid1,mid2+1,d,tree[rt].son[i]);

232             }

233         }

234         if(x2>mid1)

235         {

236             if(y1<=mid2)

237             {

238                 for(;tree[rt].kind[i]!=3&&i<tree[rt].cnt;i++);

239                 if(tree[rt].kind[i]==3)

240                     Query(x1,x2,y1,y2,mid1+1,b,c,mid2,tree[rt].son[i]);

241             }

242             if(y2>mid2)

243             {

244                 for(;tree[rt].kind[i]!=4&&i<tree[rt].cnt;i++);

245                 if(tree[rt].kind[i]==4)

246                     Query(x1,x2,y1,y2,mid1+1,b,mid2+1,d,tree[rt].son[i]);

247             }

248         }

249     }

250 }

251 int main()

252 {

253     int n,m,q;

254     int x1,y1,x2,y2,val,flag;

255     while(~scanf("%d%d%d",&n,&m,&q))

256     {

257         size=2;

258         Build(1,n,1,m,1);

259         while(q--)

260         {

261             scanf("%d%d%d%d%d",&flag,&x1,&y1,&x2,&y2);

262             if(flag==1)

263             {

264                 scanf("%d",&val);

265                 Add(x1,x2,y1,y2,val,1,n,1,m,1);

266             }

267             else if(flag==2)

268             {

269                 scanf("%d",&val);

270                 Cover(x1,x2,y1,y2,val,1,n,1,m,1);

271             }

272             else

273             {

274                 SUM=BIG=0;

275                 SMALL=INF;

276                 Query(x1,x2,y1,y2,1,n,1,m,1);

277                 printf("%d %d %d\n",SUM,SMALL,BIG);

278             }

279         }

280     }

281     return 0;

282 }

你可能感兴趣的:(Matrix)