SRM542div2(500分)

题目大意:给定一个直角坐标(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;
        }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值