题目大意:给定一个直角坐标(1-X , 1-Y).在这个区域里面寻找一对点A,B,C.使得A->B+B->C+C->A的距离之和在minT和maxT之间
其中A->B的距离表示X和Y互相对减的绝对值 3 < X,Y <= 4000 .. 1 < maxT <20000. 样例给出为X Y minT maxT
解题思路:如果是暴力枚举的方法的话,应该是所有的点X*Y^3的复杂度.太大了.
画出第一个 3 3 1 2000 .. 结果是6..
对于一对满足情况的节点.将其三个点分别投影到X轴和Y轴后可以发现..就X轴而言.其在X轴上贡献的距离是最右边减去最左边的节点*2.
在Y轴上的值也是一样的.. 那么在坐标系里面..对于一个在X轴上贡献了a距离的一对点,只需要找到再Y轴上贡献剩余价值的点就可以了...
同时注意最后还要*6. 就第一个样例就可以很容易发现..
void cc(int n , LL d[])
{
for(int i = 1 ; i < n ; i++)
{
for(int j = i + 2 ; j <= n ; j++)d[2*(j-i)] = ( d[2*(j-i)] + j - i - 1) % mod;
}
}
LL Get(int x)
{
LL res = 0;
for(int i = 1 ; i < x ; i++)
{
res = (res + disx[i] * sumy[x-i] * 6 )%mod;
}
return res;
}
int countRoutes(int X, int Y, int minT, int maxT)
{
memset(disx,0,sizeof(disx));
memset(disy,0,sizeof(disy));
memset(sumx,0,sizeof(sumx));
memset(sumy,0,sizeof(sumy));
cc(X,disx);cc(Y,disy);
for(int i = 1 ; i <= maxT ; i++)sumx[i] = (sumx[i-1] + disx[i])%mod;
for(int i = 1 ; i <= maxT ; i++)sumy[i] = (sumy[i-1] + disy[i])%mod;
// cout<<"1"<<endl;
return ( Get(maxT) - Get(minT - 1) + mod ) % mod;
}