【JZOJ3598】【CQOI2014】数三角形

Description

这里写图片描述

Data Constraint

对于30%的数据 1<=m,n<=10

对于100%的数据 1<=m,n<=1000

Solution

这道题其实很水,虽然我考场上打挂了。我们正难则反。ans=在N*M的网格中任意三点的方案数-三点成直线的方案。现在问题成了如何求三点成直线的方案。我们枚举一个长为x,宽为y的矩阵,强制有两点放在该矩阵的左上角和右下角。现在只要求在该矩阵中有多少点在左上角到右下角的直线上。数量显然是 gcd(x,y)1 。而在N*M的网格中长为x,宽为y的矩阵的数量为 (n+1x)(m+1y)

Code

#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn=1e6+5;
struct code{
    int a,b;
}b[maxn];
ll n,m,i,t,j,k,l,x,y,z,ans,num;
ll dg(ll x){
    return x*(x-1)*(x-2)/6;
}
int pan(ll x,ll y){
    ll r=x%y;
    while (r) x=y,y=r,r=x%y;
    return y;
}
bool cmp(code x,code y){
    return x.b<y.b || x.b==y.b&& x.a<y.a;
}
int main(){
//  freopen("data.in","r",stdin);
    scanf("%lld%lld",&n,&m);n++;m++;
    t=n*m;
    ans=dg(t)-n*dg(m)-m*dg(n);
    for (i=2;i<n;i++)
        for (j=2;j<m;j++){
            t=pan(i,j);
            if (t<2) continue;t--;
            ans-=(n-i)*(m-j)*t*2;
        }
    printf("%lld\n",ans);
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值