码迷,mamicode.com
首页 > 其他好文 > 详细

topcoder练习记

时间:2016-03-10 14:42:20      阅读:138      评论:0      收藏:0      [点我收藏+]

标签:

自己做过的题太少了>_<

找一些tc的题来刷一刷吧 ^_^

 

SRM 600 div1 hard LotsOfLines

有 y = ax+b (0 <= a < A && 0 <= b < B) 这样 A*B 条直线, 问你最终这些直线把平面分成了几部分。

 考虑以a为第一关键字b为第二关键字给直线排序然后一条一条地加进去并计算贡献, 显然每一条边加进去的时候就是它和原图的交点个数+1, 因为a相同的两条直线必然没有交点, 所以可以把当前的图理解成这样 : y = cx+d(0 <= c < a && 0 <= d < B) , 他们的交点个数就是 x = (d-b)/(a-c) 有多少种取值, 即 x = (-b ~ B-b-1) / (1 ~ a) 有多少种取值, 发现分子和分母都是 < A 的且始终是自然数上的一个前缀, 于是 A^2 预处理一下就可以了。 判断 a/b 有没有在前面出现过可以直接用gcd, 不存在 c/d (0 <= c < a && 0 <= c < b) 且 c/d == a/b 当且仅当 gcd(a, b) == 1 (显然)。

技术分享
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define MAXN 1205
#define ll long long
using namespace std;

class LotsOfLines{
    public:
    int f[MAXN][MAXN];
    ll ans;
    int gcd(int a, int b){return b == 0 ? a : gcd(b, a%b);}
    ll countDivisions(int A, int B){
        for(int i = 1; i < A; i ++)
        for(int j = 1; j < B; j ++)
            f[i][j] = f[i][j-1] + f[i-1][j] - f[i-1][j-1] + (gcd(i,j)==1 ? 1 : 0);
    for(int i = 1; i < A; i ++)
        for(int j = 0; j < B; j ++){
            ans += (f[i][j] + f[i][B-j-1] + 1);
        }
        return ans + (ll)A*B + 1;
    }
};
View Code

 

topcoder练习记

标签:

原文地址:http://www.cnblogs.com/lixintong911/p/5261535.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!