【学习笔记】Triangles

套一下公式然后完

根据对称性,不妨考虑 ( 0 , i ) , ( j , 0 ) , ( W , k ) (0,i),(j,0),(W,k) (0,i),(j,0),(W,k)围成的三角形,同时假设 i < k i<k i<k

套用 Pick \text{Pick} Pick定理: 2 S = a + b − 2 2S=a+b-2 2S=a+b2

得到 j ( k − i ) + W i = 2 a + gcd ⁡ ( i , j ) + gcd ⁡ ( W − j , k ) + gcd ⁡ ( W , k − i ) − 2 j(k-i)+Wi=2a+\gcd(i,j)+\gcd(W-j,k)+\gcd(W,k-i)-2 j(ki)+Wi=2a+gcd(i,j)+gcd(Wj,k)+gcd(W,ki)2

既然前面假设 k > i k>i k>i,那么我们令 d = k − i d=k-i d=ki,这样所有数都是正数。

j d + W i = 2 a + gcd ⁡ ( i , j ) + gcd ⁡ ( W − j , k ) + gcd ⁡ ( W , k − i ) − 2 jd+Wi=2a+\gcd(i,j)+\gcd(W-j,k)+\gcd(W,k-i)-2 jd+Wi=2a+gcd(i,j)+gcd(Wj,k)+gcd(W,ki)2

瞪眼法不难看出此时 j , d j,d j,d的对数是调和级数。那么我们枚举 j , d j,d j,d,这样只剩下变量 i i i

j d − gcd ⁡ ( W , d ) + 2 = 2 a + gcd ⁡ ( i , j ) + gcd ⁡ ( W − j , d + i ) − W i jd-\gcd(W,d)+2=2a+\gcd(i,j)+\gcd(W-j,d+i)-Wi jdgcd(W,d)+2=2a+gcd(i,j)+gcd(Wj,d+i)Wi

换成不等式:

W i ≤ − j d + gcd ⁡ ( W , d ) + gcd ⁡ ( i , j ) + gcd ⁡ ( W − j , d + i ) − 2 + 2 K Wi\le -jd+\gcd(W,d)+\gcd(i,j)+\gcd(W-j,d+i)-2+2K Wijd+gcd(W,d)+gcd(i,j)+gcd(Wj,d+i)2+2K

不难发现当 i ≤ ⌊ − j d + gcd ⁡ ( W , d ) − 2 + 2 K W ⌋ i\le \lfloor\frac{-jd+\gcd(W,d)-2+2K}{W}\rfloor iWjd+gcd(W,d)2+2K时一定合法,因此只需检验 ⌊ − j d + gcd ⁡ ( W , d ) − 2 + 2 K W ⌋ + 1 \lfloor\frac{-jd+\gcd(W,d)-2+2K}{W}\rfloor+1 Wjd+gcd(W,d)2+2K+1即可,可以 O ( 1 ) O(1) O(1)判断。

复杂度 O ( n log ⁡ 2 n ) O(n\log^2 n) O(nlog2n)

#include<bits/stdc++.h>
#define ll long long
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
#define db long double
#define cpx complex<db>
#define inf 0x3f3f3f3f3f3f3f3f
using namespace std;
int W,H,K;
ll res;
int gcd(int x,int y){
	return y==0?x:gcd(y,x%y);
}
ll solve(int W,int H){
	ll res=0;
	for(int j=1;j<W;j++){
		for(int d=1;d<H&&j*d<=K*2+W;d++){
			int i=(-j*d+gcd(W,d)-2+2*K)/W;i=min(i,H-d-1);i=max(i,0);
			assert(i>=0);res+=i;
			if(i!=H-d-1&&W*(i+1)<=-j*d+gcd(W,d)+gcd(i+1,j)+gcd(W-j,d+i+1)-2+2*K)res++;
		}
	}res<<=1;
	for(int j=1;j<W;j++){
		int i=(2*K+W-2)/W;i=min(i,H-1);i=max(i,0);
		assert(i>=0);res+=i;
		if(i!=H-1&&W*(i+1)<=2*K+gcd(i+1,j)+gcd(W-j,i+1)+W-2)res++;
	}return res;
}
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    cin>>W>>H>>K;
    cout<<(solve(W,H)+solve(H,W)<<1);
}
posted @ 2023-02-01 15:51  仰望星空的蚂蚁  阅读(41)  评论(0)    收藏  举报  来源