Codeforces 1080C 题解(思维+二维前缀和)
题面
题目大意:
有一个黑白的棋盘,现在将棋盘上的一个子矩形全部染成黑色,另一个子矩形全部染成白色
求染完色后黑,白格子的总数
分析
我们可以发现,对于一个(1,1)到(x,y)的矩形,若xy为偶数,则黑、白的个数都是 $ \frac{xy}{2} $
若xy为奇数,则黑格个数为\(\ [ \frac{xy}{2} \ ]\),白格个数为\(\ [ \frac{xy}{2} \ ]+1\)
因此用二维前缀和的方法就可以求出任意子矩形内的黑,白格子个数
long long get_white(long long x,long long y) {
if((x*y)%2==0) return (x*y)/2;
else {
return (x*y)/2+1;
}
}
long long get_black(long long x,long long y) {
if((x*y)%2==0) return (x*y)/2;
else {
return (x*y)/2;
}
}
long long get_rec_black(long long x1,long long y1,long long x2,long long y2) {
return get_black(x2,y2)-get_black(x1-1,y2)-get_black(x2,y1-1)+get_black(x1-1,y1-1);
}
long long get_rec_white(long long x1,long long y1,long long x2,long long y2) {
return get_white(x2,y2)-get_white(x1-1,y2)-get_white(x2,y1-1)+get_white(x1-1,y1-1);
}
然后考虑修改:
对于染黑的操作,设wsum,bsum分别表示整个棋盘里的白,黑格子个数,初始wsum,bsum都是原本棋盘里黑,白格子的个数
s表示染黑的矩形内部原来白色格子个数,则wsum=wsum-s,bsum=bsum+s
染白操作同理
wsum=get_white(n,m);
bsum=get_black(n,m);
s1=get_rec_black(x1,y1,x2,y2);
wsum+=s1;
bsum-=s1;
但这样会导致一个问题,若染黑和染白的矩形有公共部分,那么会出现错误
因此我们染黑时先不考虑公共部分(染白时直接染),把公共部分从答案里面减去
再分析公共部分对答案的影响
设公共部分面积为same
则bsum+=same,wsum-=same
这样我们就在\(O(1)\)时间内求出了答案
代码
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int t;
long long n,m;
long long x1,y1,x2,y2;
long long x3,y3,x4,y4;
long long wsum,bsum;
long long get_white(long long x,long long y) {
if((x*y)%2==0) return (x*y)/2;
else {
return (x*y)/2+1;
}
}
long long get_black(long long x,long long y) {
if((x*y)%2==0) return (x*y)/2;
else {
return (x*y)/2;
}
}
long long get_rec_black(long long x1,long long y1,long long x2,long long y2) {
return get_black(x2,y2)-get_black(x1-1,y2)-get_black(x2,y1-1)+get_black(x1-1,y1-1);
}
long long get_rec_white(long long x1,long long y1,long long x2,long long y2) {
return get_white(x2,y2)-get_white(x1-1,y2)-get_white(x2,y1-1)+get_white(x1-1,y1-1);
}
long long minx,miny,maxx,maxy;
int get_inter(long long x1,long long y1,long long x2,long long y2,long long x3,long long y3,long long x4,long long y4) {
minx=max(x1,x3);
miny=max(y1,y3);
maxx=min(x2,x4);
maxy=min(y2,y4);
if(minx>maxx||miny>maxy) return -1;
else return 1;
}
int main() {
long long s1,s2,same;
scanf("%d",&t);
while(t--) {
scanf("%I64d %I64d",&n,&m);
// swap(n,m);
scanf("%I64d %I64d %I64d %I64d",&x1,&y1,&x2,&y2);
scanf("%I64d %I64d %I64d %I64d",&x3,&y3,&x4,&y4);
wsum=get_white(n,m);
bsum=get_black(n,m);
s1=get_rec_black(x1,y1,x2,y2);
wsum+=s1;
bsum-=s1;
if(get_inter(x1,y1,x2,y2,x3,y3,x4,y4)==-1) {
s2=get_rec_white(x3,y3,x4,y4);
bsum+=s2;
wsum-=s2;
} else {
s2=get_rec_white(x3,y3,x4,y4)-get_rec_white(minx,miny,maxx,maxy);
bsum+=s2;
wsum-=s2;
bsum+=(maxy-miny+1)*(maxx-minx+1);
wsum-=(maxy-miny+1)*(maxx-minx+1);
}
printf("%I64d %I64d\n",wsum,bsum);
}
}
Codeforces 1080C 题解(思维+二维前缀和)的更多相关文章
- Codeforces 835C - Star sky - [二维前缀和]
题目链接:http://codeforces.com/problemset/problem/835/C 题意: 在天空上划定一个直角坐标系,有 $n$ 颗星星,每颗星星都有坐标 $(x_i,y_i)$ ...
- Codeforces 838A - Binary Blocks(二维前缀和+容斥)
838A - Binary Blocks 思路:求一下前缀和,然后就能很快算出每一小正方块中1的个数了,0的个数等于k*k减去1的个数,两个的最小值就是要加进答案的值. 代码: #include< ...
- CDOJ 1256 二维前缀和处理
昊昊喜欢运动 他NN 天内会参加MM 种运动(每种运动用一个[1,m][1,m] 的整数表示) 舍友有QQ 个问题 问昊昊第ll 天到第rr 天参加了多少种不同的运动 Input 输入两个数NN , ...
- 【题解】洛谷P2822 [NOIP2016TG ]组合数问题 (二维前缀和+组合数)
洛谷P2822:https://www.luogu.org/problemnew/show/P2822 思路 由于n和m都多达2000 所以暴力肯定是会WA的 因为整个组合数是不会变的 所以我们想到存 ...
- Codeforces 1262E Arson In Berland Forest(二维前缀和+二维差分+二分)
题意是需要求最大的扩散时间,最后输出的是一开始的火源点,那么我们比较容易想到的是二分找最大值,但是我们在这满足这样的点的时候可以发现,在当前扩散时间k下,以这个点为中心的(2k+1)2的正方形块内必 ...
- C - Monitor CodeForces - 846D (二维前缀和 + 二分)
Recently Luba bought a monitor. Monitor is a rectangular matrix of size n × m. But then she started ...
- COGS1752 [BOI2007]摩基亚Mokia(CDQ分治 + 二维前缀和 + 线段树)
题目这么说的: 摩尔瓦多的移动电话公司摩基亚(Mokia)设计出了一种新的用户定位系统.和其他的定位系统一样,它能够迅速回答任何形如“用户C的位置在哪?”的问题,精确到毫米.但其真正高科技之处在于,它 ...
- poj-3739. Special Squares(二维前缀和)
题目链接: I. Special Squares There are some points and lines parellel to x-axis or y-axis on the plane. ...
- Good Bye 2015 C. New Year and Domino 二维前缀
C. New Year and Domino They say "years are like dominoes, tumbling one after the other". ...
随机推荐
- Python之路-pandas包的详解与使用
什么是pandas pandas是一种Python数据分析的利器,是一个开源的数据分析包,最初是应用于金融数据分析工具而开发出来的,因此pandas为时间序列分析提供了很好的支持.pandas是PyD ...
- How to compile and install Linux Kernel 5.1.2 from source code
How to compile and install Linux Kernel 5.1.2 from source code Compiling a custom kernel has its adv ...
- 网络拓扑_配置hybrid端口
目的:实现不同VLAN间的PC不可互访, 但不同VLAN的PC均可以访问服务器. 例: VLAN5与VLAN10的PC不可以互通,但它们均可与服务器VLAN50互通. 拓扑图:
- MemCache--01 解决session
目录 1. MemCache介绍 2.Session与Cookie介绍 3. 安装部署Nginx 4. 安装部署PHP 5. 安装Mariadb数据库 6. 部署网站(phpMyAdmin) 7. 部 ...
- spring boot generator
pom.xml 插件引用依赖 <build> <plugins> <plugin> <groupId>org.springframework.boot& ...
- LA 6834 Shopping
题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...
- centos 6.5 安装 maven
从nexus官网下载Nexus Repository Manager OSS 2.x的安装包:nexus-2.14.1-01-bundle.tar.gz,3.x版本需要jdk8及以上 解压 tar x ...
- File类常用的方法与字节流类方法简介
File类常用的方法 获取功能的方法 public String getAbsolutePath() :返回此File的绝对路径名字符串. public String getPath() :将此Fil ...
- securityDemopom
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> &l ...
- C#第一个程序Helloworld