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. OC - 4.OC核心语法

    一.点语法 1> 基本使用 点语法本质上是set方法/get方法的调用 2> 使用注意 若出现在赋值操作符的右边,在执行时会转换成get方法 若出现在赋值操作符的左边,在执行时会转换成se ...

  2. O-C-11-利用类方法做一个简单的计算器

    #import <Foundation/Foundation.h> @interface calculator : NSObject //@property  double    numb ...

  3. ZOJ 1091 (HDU 1372) Knight Moves(BFS)

    Knight Moves Time Limit: 2 Seconds      Memory Limit: 65536 KB A friend of you is doing research on ...

  4. Qt 获得终端执行结果

    代码 话不多直接上本人代码 void MainWindow::on_pushButton_3_clicked() { myprocess = new QProcess(this); myprocess ...

  5. Android中为窗口定义主题

    在res/values/styles文件夹中定义如下: <style name="myTheme"> <item name="android:windo ...

  6. Swift语言 1小时速学教程

    本文由 张渊杰 (网名寂静)编写 Swift语言 1小时速学教程 写在前面的话 有些人可能想, 呵呵, 1小时学一门语言, 你不是搞笑吧, 我想说, 是的, 完全可以, 就要看你怎么学了 要想在1小时 ...

  7. 规则引擎-BRMS在企业开发中的应用

    1. 什么是规则复杂企业级项目的开发以及其中随外部条件不断变化的业务规则(business logic),迫切需要分离商业决策者的商业决策逻辑和应用开发者的技术决策,并把这些商业决策放在中心数据库或其 ...

  8. sonar-maven-plugin问题

    问题: jenkins本地构建时sonar报错 StackOverflow问题 [ERROR] Failed to execute goal org.codehaus.mojo:sonar-maven ...

  9. Yii 跨域设置

    控制器设置: abstract class ControllerBase extends Controller { public function __construct($id, $module, ...

  10. 整理 iOS 9 适配中出现的坑(图文)

    作者:董铂然 授权本站转载. 本文主要是说一些iOS9适配中出现的坑,如果只是要单纯的了解iOS9新特性可以看瞄神的开发者所需要知道的 iOS 9 SDK 新特性.9月17日凌晨,苹果给用户推送了iO ...