专栏文章
SP6408 KKKCT2 - Counting Triangles 2 题解
SP6408题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mipspoqe
- 此快照首次捕获于
- 2025/12/03 17:19 3 个月前
- 此快照最后确认于
- 2025/12/03 17:19 3 个月前
前置知识
等差数列求和公式
解法
考虑枚举直角顶点 ,然后分为了 种贡献情况。

设 , 种情况的贡献分别为 ,加起来后得到 ,但没有什么可以优化的地方。
观察乘积项,以 为例,考虑固定 这个常量,统计 的贡献,分讨 划分成的三个区间内部的转移即可。
代码
CPP#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define sort stable_sort
#define endl '\n'
using namespace std;
const ll p=2009;
ll s1(ll n)
{
return n*(n+1)/2;
}
ll s2(ll n)
{
return n*(n+1)*(2*n+1)/6;
}
ll ask(ll up,ll a,ll b)
{
ll ans=0;
ans+=s1(min(a,up))+max(0ll,(up-a))*a;//2e8
ans+=s2(min(min(a,b)-1,up));//2e12
if(min(min(a,b)-1,up)<min(max(a,b),up))
ans+=(min(min(a,b)-1,up)+1+min(max(a,b),up))*(min(max(a,b),up)-min(min(a,b)-1,up))/2*min(a,b);//2e12
ans+=max(0ll,(up-max(a,b)))*a*b;//1e12
return ans;
}
int main()
{
// #define Isaac
#ifdef Isaac
freopen("count.in","r",stdin);
freopen("count.out","w",stdout);
#endif
int t,x,y,i,j;
ll ans;
cin>>t;
for(;t>=1;t--)
{
cin>>x>>y; ans=0;
// a=min(i,y-j),b=min(x-i,j),c=min(i,j),d=min(x-i,y-j)
for(i=0;i<=x;i++)
{
ans+=ask(y,i,x-i);// bc+c
ans+=ask(y,x-i,i);// ad+d
}
for(i=0;i<=y;i++)
{
ans+=ask(x,y-i,i);// ac+a
ans+=ask(x,i,y-i);// bd+b
}
cout<<ans%p<<endl;
}
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...