【学习笔记】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); }

__EOF__

本文作者仰望星空的蚂蚁
本文链接https://www.cnblogs.com/cqbzly/p/17530035.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   仰望星空的蚂蚁  阅读(19)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
点击右上角即可分享
微信分享提示