uva 12508 - Triangles in the Grid(几何+计数)

这个题写了一下午,看题解看了很旧才看懂

详细题解是别人的http://www.tuicool.com/articles/YzYrEf

看完题解,在求第二部分时上界和下界的公式为(m*x+k)/n为上界

(m*x-k)/n+1为下界

第三部分是固定一个顶点,然后在一条边上移动第二个点,最后利用范围求出第三个点

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<queue>
#include<cmath>
#include<algorithm>
using namespace std;
#define MST(vis,x) memset(vis,x,sizeof(vis))
#define maxn 220
#define ll long long
#define mod 1000000007
#define pi acos(-1.0)
#define eps 1e-8
ll n,m,A,B;
ll ans,sum;
ll solve(ll limit)
{
    sum=0;
    if(limit<0)limit=0;
    if(n>m)swap(n,m);
    for(ll i=1;i<=n;i++)
    {
        for(ll j=1;j<=m;j++)
        {
           ans=0;
           if(i*j<=limit)ans+=2*(i+j-2);
           for(ll a=0;a<=i;a++)
           {
               ll r=(a*j+limit)/i;
               if(r>j)r=j;
               ll l=a*j-limit;
               if(l<=0)l=0;
               else
                l=(l-1)/i+1;
                ans+=2*(r-l+1);
           }
           for(ll a=1;a<i;a++)
           {
               ll temp=i*j-a;
               if(temp<=limit)
                   ans+=4*(j-1);
                else
                {
                    temp-=limit;
                    ll u=j-1-min(temp/a+(temp%a!=0),j-1);
                    ans+=4*u;
                }
           }
           sum+=ans*(n-i+1)*(m-j+1);
        }
    }
    return sum;
}
int main()
{
    ll t;
    scanf("%lld",&t);
    while(t--)
    {
        scanf("%lld%lld%lld%lld",&n,&m,&A,&B);
        printf("%lld\n",solve(2*B)-solve(2*A-1));
    }
    return 0;
}

 

posted @ 2017-10-12 16:37  被咬过的馒头  阅读(149)  评论(0编辑  收藏  举报