Description

上帝说,不要圆,要方,于是便有了这道题。由于我们应该方,而且最好能够尽量方,所以上帝派我们来找正方形
上帝把我们派到了一个有N行M列的方格图上,图上一共有(N+1)×(M+1)个格点,我们需要做的就是找出这些格点形
成了多少个正方形(换句话说,正方形的四个顶点都是格点)。但是这个问题对于我们来说太难了,因为点数太多
了,所以上帝删掉了这(N+1)×(M+1)中的K个点。既然点变少了,问题也就变简单了,那么这个时候这些格点组成
了多少个正方形呢?

Input

第一行三个整数 N, M, K, 代表棋盘的行数、 列数和不能选取的顶点个数。 保证 N, M >= 1, K <=(N + 1) ×
(M + 1)。约定每行的格点从上到下依次用整数 0 到 N 编号,每列的格点依次用 0到 M 编号。接下来 K 行,每
行两个整数 x,y 代表第 x 行第 y 列的格点被删掉了。保证 0 <=x <=N<=10^6, 0 <=y<=M<=10^6,K<=2*1000且不
会出现重复的格点。

Output

仅一行一个正整数, 代表正方形个数对 100000007( 10^8 + 7) 取模之后的值

Sample Input

2 2 4
1 0
1 2
0 1
2 1

Sample Output

1
  这道题因为k很小可以用容斥, 所有正方形数-Σ每个点(在正方形上)的正方形数+Σ每个无序点对(在正方形上)的正方形数-Σ每个无序三个元组(在正方形上)的正方形数+Σ每个四元组(在正方形上)的正方形数
  然后我打的复杂化了,不过很好懂,几乎是望文生义……
 #include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int N=;
const int Mod=;
typedef long long LL;
LL Abs(LL x){return x<?-x:x;}
LL n,m,k,tot,x[N],y[N];
LL Ask(LL a,LL b,LL c){
LL ret,L;
if(!a||!b||!c)return ;
if(a>c-)a=c-;
if(b>c-)b=c-;
ret=(*c-a-)*a/;
if(c->=b+){
L=min(a,c-b-);
ret+=b*L;
ret-=(*c-L-)*L/;
}
return (ret%Mod+Mod)%Mod;
}
LL Solve1(){
LL ret=,L,R,U,D;
for(int i=;i<=k;i++){
L=min(x[i]-,y[i]-);ret+=L;
L=min(n+-x[i],y[i]-);ret+=L;
L=min(x[i]-,m+-y[i]);ret+=L;
L=min(n+-x[i],m+-y[i]);ret+=L;
}
for(int i=;i<=k;i++){
U=x[i]-;D=n+-x[i];
L=y[i]-;R=m+-y[i];
ret+=Ask(L,R,U);
ret+=Ask(L,R,D);
ret+=Ask(U,D,L);
ret+=Ask(U,D,R);
}
return ret%Mod;
} LL Solve2(){
LL ret=,L;
LL px,py,dx,dy;
for(int i=;i<=k;i++)
for(int j=i+;j<=k;j++){
dx=x[j]-x[i];
dy=y[j]-y[i]; px=x[j]+dy;py=y[j]-dx;
if(px>=&&px<=n+&&py>=&&py<=m+){
px=px-dx;py=py-dy;
if(px>=&&px<=n+&&py>=&&py<=m+)ret+=;
} px=x[j]-dy;py=y[j]+dx;
if(px>=&&px<=n+&&py>=&&py<=m+){
px=px-dx;py=py-dy;
if(px>=&&px<=n+&&py>=&&py<=m+)ret+=;
} if((x[i]+x[j])%==(y[i]+y[j])%){
dx=*x[i]-(x[i]+x[j]);
dy=*y[i]-(y[i]+y[j]);
px=(x[i]+x[j]+dy)/;
py=(y[i]+y[j]-dx)/;
if(px>=&&px<=n+&&py>=&&py<=m+){
dx=-dx;dy=-dy;
px=(x[i]+x[j]+dy)/;
py=(y[i]+y[j]-dx)/;
if(px>=&&px<=n+&&py>=&&py<=m+)ret+=;
}
}
}
return ret%Mod;
} LL hshx[N],hshy[N];
int cntx,cnty,vis[N][N]; void Prepare(){
for(int i=;i<=k;i++){
hshx[++cntx]=x[i];
hshy[++cnty]=y[i];
}
sort(hshx+,hshx+cntx+);
cntx=unique(hshx+,hshx+cntx+)-hshx-;
sort(hshy+,hshy+cnty+);
cnty=unique(hshy+,hshy+cnty+)-hshy-;
for(int i=;i<=k;i++){
LL x_=lower_bound(hshx+,hshx+cntx+,x[i])-hshx;
LL y_=lower_bound(hshy+,hshy+cnty+,y[i])-hshy;
vis[x_][y_]=i;
}
} int Q(LL x,LL y){
LL x_=lower_bound(hshx+,hshx+cntx+,x)-hshx;
LL y_=lower_bound(hshy+,hshy+cnty+,y)-hshy;
return (hshx[x_]==x&&hshy[y_]==y)*vis[x_][y_];
} LL Solve3(){
LL ret=;
LL px1,py1,px2,py2,dx,dy;
for(int i=;i<=k;i++)
for(int j=i+;j<=k;j++){
dx=x[j]-x[i];
dy=y[j]-y[i]; px1=x[j]+dy;py1=y[j]-dx;
if(px1>=&&px1<=n+&&py1>=&&py1<=m+){
px2=px1-dx;py2=py1-dy;
if(px2>=&&px2<=n+&&py2>=&&py2<=m+){
if(Q(px1,py1)>j)ret+=;
if(Q(px2,py2)>j)ret+=;
}
} px1=x[j]-dy;py1=y[j]+dx;
if(px1>=&&px1<=n+&&py1>=&&py1<=m+){
px2=px1-dx;py2=py1-dy;
if(px2>=&&px2<=n+&&py2>=&&py2<=m+){
if(Q(px1,py1)>j)ret+=;
if(Q(px2,py2)>j)ret+=;
}
} if((x[i]+x[j])%==(y[i]+y[j])%){
dx=*x[i]-(x[i]+x[j]);
dy=*y[i]-(y[i]+y[j]);
px1=(x[i]+x[j]+dy)/;
py1=(y[i]+y[j]-dx)/;
if(px1>=&&px1<=n+&&py1>=&&py1<=m+){
dx=-dx;dy=-dy;
px2=(x[i]+x[j]+dy)/;
py2=(y[i]+y[j]-dx)/;
if(px2>=&&px2<=n+&&py2>=&&py2<=m+){
if(Q(px1,py1)>j)ret+=;
if(Q(px2,py2)>j)ret+=;
}
}
}
}
return ret%Mod;
} LL Solve4(){
LL ret=;
LL px1,py1,px2,py2,dx,dy;
for(int i=;i<=k;i++)
for(int j=i+;j<=k;j++){
dx=x[j]-x[i];
dy=y[j]-y[i]; px1=x[j]+dy;py1=y[j]-dx;
if(px1>=&&px1<=n+&&py1>=&&py1<=m+){
px2=px1-dx;py2=py1-dy;
if(px2>=&&px2<=n+&&py2>=&&py2<=m+)
if(Q(px1,py1)>j&&Q(px2,py2)>j)ret+=;
} px1=x[j]-dy;py1=y[j]+dx;
if(px1>=&&px1<=n+&&py1>=&&py1<=m+){
px2=px1-dx;py2=py1-dy;
if(px2>=&&px2<=n+&&py2>=&&py2<=m+)
if(Q(px1,py1)>j&&Q(px2,py2)>j)ret+=;
} if((x[i]+x[j])%==(y[i]+y[j])%){
dx=*x[i]-(x[i]+x[j]);
dy=*y[i]-(y[i]+y[j]);
px1=(x[i]+x[j]+dy)/;
py1=(y[i]+y[j]-dx)/;
if(px1>=&&px1<=n+&&py1>=&&py1<=m+){
dx=-dx;dy=-dy;
px2=(x[i]+x[j]+dy)/;
py2=(y[i]+y[j]-dx)/;
if(px2>=&&px2<=n+&&py2>=&&py2<=m+)
if(Q(px1,py1)>j&&Q(px2,py2)>j)ret+=;
}
}
}
return ret%Mod;
} int main(){
freopen("square.in","r",stdin);
freopen("square.out","w",stdout);
scanf("%lld%lld%lld",&n,&m,&k);
for(LL L=min(m,n);L>=;L--){
tot+=(n-L+)*(m-L+)%Mod*L%Mod;
if(tot>=Mod)tot-=Mod;
}
for(int i=;i<=k;i++){
scanf("%lld%lld",&x[i],&y[i]);
x[i]+=;y[i]+=;
}
Prepare();
tot-=Solve1();tot%=Mod;
tot+=Solve2();tot%=Mod;
tot-=Solve3();tot%=Mod;
tot+=Solve4();tot%=Mod;
tot=(tot+Mod)%Mod;
printf("%lld\n",tot);
return ;
}

  运算有些多,常数比较大,不开O2只有50分,优化的话,可以把LL改成int,Mod的时候有些地方可以改成减。

数学(容斥计数):LNOI 2016 方的更多相关文章

  1. 【BZOJ 4455】 [Zjoi2016]小星星 容斥计数

    dalao教导我们,看到计数想容斥……卡常策略:枚举顺序.除去无效状态.(树结构) #include <cstdio> #include <cstring> #include ...

  2. BZOJ 2005 [Noi2010]能量采集 (数学+容斥 或 莫比乌斯反演)

    2005: [Noi2010]能量采集 Time Limit: 10 Sec  Memory Limit: 552 MBSubmit: 4493  Solved: 2695[Submit][Statu ...

  3. Codeforces.997C.Sky Full of Stars(容斥 计数)

    题目链接 那场完整的Div2(Div1 ABC)在这儿.. \(Description\) 给定\(n(n\leq 10^6)\),用三种颜色染有\(n\times n\)个格子的矩形,求至少有一行或 ...

  4. 一本通 1783 矩阵填数 状压dp 容斥 计数

    LINK:矩阵填数 刚看到题目的时候感觉是无从下手的. 可以看到有n<=2的点 两个矩形. 如果只有一个矩形 矩形外的方案数容易计算考虑 矩形内的 必须要存在x这个最大值 且所有值<=x. ...

  5. CF1487G String Counting (容斥计数)

    传送门 考虑$c[i]>n/3$这个关键条件!最多有2个字母数量超过$n/3$! 没有奇数回文?长度大于3的回文串中间一定是长度为3的回文串,所以合法串一定没有长度=3的回文,也就是$a[i]\ ...

  6. ABC209F. Deforestation——DP(、数学容斥)

    题面 有 n n n 棵树排成一排,每棵树高度为 h i ( i ∈ [ 1 , n ] ) h_i~(i\in[1,n]) hi​ (i∈[1,n]) ,你现在要按照一个排列 P P P 的顺序去砍 ...

  7. 【BZOJ 4818】 4818: [Sdoi2017]序列计数 (矩阵乘法、容斥计数)

    4818: [Sdoi2017]序列计数 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 560  Solved: 359 Description Al ...

  8. Co-prime HDU - 4135_容斥计数

    Code: #include<cstdio> #include<cstring> #include<cmath> #include<iostream> ...

  9. How many integers can you find HDU - 1796_容斥计数

    Code: #include<cstdio> using namespace std; typedef long long ll; const int R=13; ll a[R]; ll ...

随机推荐

  1. sharepoint2013 新建母板页 新建页面布局 关联母板页和页面布局

    1     母板页的应用和layout(页面布局)的创建和应用 母板页上传:将准备好的html和样式 通过spd中的导入方式导入模版html, 导入后: 然后在网站设置中进行转换为母板页.  随后编辑 ...

  2. 01_JavaMail_03_邮件发送简单实例

    [JavaMail中的核心类] 1.Session:类似Jdbc中的Connection的作用 2.MimeMessage:邮件信息类 3.Transport:发送器,用来发送邮件 [工程截图] [具 ...

  3. 为什么aspx这么“慢”

    首先你要明白什么viewstate:由系统生成的一个隐藏域,用来进行页面状态保持的 里面存放着关于判断页面是否提交的Ispostback,和一些关于服务器控件的状态和数据: (说明下 ,ViewSta ...

  4. Linux的进程优先级

    Linux的进程优先级 为什么要有进程优先级?这似乎不用过多的解释,毕竟自从多任务操作系统诞生以来,进程执行占用cpu的能力就是一个必须要可以人为控制的事情.因为有的进程相对重要,而有的进程则没那么重 ...

  5. cp 命令参数

    cp命令         该命令的功能是将给出的文件或目录拷贝到另一文件或目录中,同MSDOS下的copy命令一样,功能十分强大.         语法: cp [选项] 源文件或目录 目标文件或目录 ...

  6. Ajax 异步 XMLHttpRequest

    1.GET方式             1.1设置参数             xhr.open("GET", "GetAreasByAjax.ashx?isAjax=1 ...

  7. [CLR VIA C#] chapter2 building,packaging,deploying, and administering

    今天整理一下 assembly, 总感觉第一章 到 第三章 没怎么仔细看, 导致后面作者说前面说过的, 我就心里不舒服, 前面3章很干很涩, 好好啃啃, 先作一些简单笔记, 最后再来 整体整理, 反正 ...

  8. SQL Server 扩展事件(Extented Events)从入门到进阶(1)——从SQL Trace到Extented Events

    由于工作需要,决定深入研究SQL Server的扩展事件(Extended Events/xEvents),经过资料搜索,发现国外大牛的系列文章,作为“学习”阶段,我先翻译这系列文章,后续在工作中的心 ...

  9. php缓存相关

    在php运行期间,php引擎要对php源码进行处理,(词法分析,语法分析等)然后生成opcode. 然后再运行.在这个阶段可以把opcode缓存起来,当下次需要运行这段程序的时候,就避免了再次 进行词 ...

  10. S3C2440触摸屏控制总结

    触摸屏控制原理,其实与ADC读取一个滑动变阻器中间触点电压的原理一样.只不过,读取触摸屏的X.Y方向上的电压需要两次,而且需要设置其工作模式以实现一个ADC读取两个通道的电压. S3C2440的ADC ...