Codeforces 933C+D C. A Colourful Prospect D. A Creative Cutout

https://blog.csdn.net/qq_28954601/article/details/79329961

C. A Colourful Prospect

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

Firecrackers scare Nian the monster, but they're wayyyyy too noisy! Maybe fireworks make a nice complement.

Little Tommy is watching a firework show. As circular shapes spread across the sky, a splendid view unfolds on the night of Lunar New Year's eve.

A wonder strikes Tommy. How many regions are formed by the circles on the sky? We consider the sky as a flat plane. A region is a connected part of the plane with positive area, whose bound consists of parts of bounds of the circles and is a curve or several curves without self-intersections, and that does not contain any curve other than its boundaries. Note that exactly one of the regions extends infinitely.

Input

The first line of input contains one integer n (1 ≤ n ≤ 3), denoting the number of circles.

The following n lines each contains three space-separated integers xy and r ( - 10 ≤ x, y ≤ 10, 1 ≤ r ≤ 10), describing a circle whose center is (x, y) and the radius is r. No two circles have the same xy and r at the same time.

Output

Print a single integer — the number of regions on the plane.

Examples

input

Copy

3
0 0 1
2 0 1
4 0 1

output

Copy

4

input

Copy

3
0 0 2
3 0 2
6 0 2

output

Copy

6

input

Copy

3
0 0 2
2 0 2
1 1 2

output

Copy

8

Note

For the first example,

For the second example,

For the third example,

题意

给定平面内 n 个圆的信息,求这些圆把平面分成了几个区域。

 

思路

久违的模板题佯~ 好开心~ 然而模板放在学校了哭唧唧 〒▽〒


求圆拆分平面有多少个区域怎么能离得开平面图的欧拉公式呢?

一般平面图欧拉公式:f=e−v+c+1f=e−v+c+1

其中 ee 代表边的数量,vv 代表点的数量,cc 代表连通块的数量,ff 代表平面区域的个数

我们把圆弧看作边,交点看作顶点,于是很容易便可以算出 e,v,ce,v,c 啦~

对于 ee ,它相当于每个圆上交点的数量和(因为这些交点把圆拆分成了这么多的弧)

对于 vv ,枚举求出交点去重即可

对于 cc ,我们已经有了无向图的边,那连通块的数量可以直接 dfs/bfs 或者并查集算出来啦~

然后套用公式就是结果了,注意精度问题。

 

AC 代码

#include<bits/stdc++.h>
#define IO ios::sync_with_stdio(false);\
    cin.tie(0);\
    cout.tie(0);
using namespace std;
typedef __int64 LL;
typedef long double Ldb;
const int maxn = 10;
const Ldb eps = 1e-12;
int n;
struct Point
{
    Ldb x,y;
    Point() {}
    Point(Ldb _x,Ldb _y):x(_x),y(_y) {}
    Point operator + (const Point &t)const
    {
        return Point(x+t.x,y+t.y);
    }
    Point operator - (const Point &t)const
    {
        return Point(x-t.x,y-t.y);
    }
    Point operator * (const Ldb &t)const
    {
        return Point(x*t,y*t);
    }
    Point operator / (const Ldb &t)const
    {
        return Point(x/t,y/t);
    }
    bool operator < (const Point &t)const
    {
        return fabs(x-t.x) < eps ? y<t.y : x<t.x;
    }
    bool operator == (const Point &t)const
    {
        return fabs(x-t.x)<eps && fabs(y-t.y)<eps;
    }
    Ldb len()const
    {
        return sqrt(x*x+y*y);
    }
    Point rot90()const
    {
        return Point(-y,x);
    }
};

struct Circle
{
    Point o;
    Ldb r;
    Circle() {}
    Circle(Point _o,Ldb _r):o(_o),r(_r) {}
    friend vector<Point> operator & (const Circle &c1,const Circle &c2)
    {
        Ldb d=(c1.o-c2.o).len();
        if(d>c1.r+c2.r+eps || d<fabs(c1.r-c2.r)-eps)
            return vector<Point>();
        Ldb dt=(c1.r*c1.r-c2.r*c2.r)/d,d1=(d+dt)/2;
        Point dir=(c2.o-c1.o)/d,pcrs=c1.o+dir*d1;
        dt=sqrt(max(0.0L,c1.r*c1.r-d1*d1)),dir=dir.rot90();
        return vector<Point> {pcrs+dir*dt,pcrs-dir*dt};
    }
} p[maxn];
bool vis[maxn];
int fa[maxn],rk[maxn];
void init()
{
    for(int i=1; i<maxn; i++)
        fa[i] = i,rk[i] = 0;
}

int find_set(int x)
{
    if(fa[x]!=x)
        fa[x] = find_set(fa[x]);
    return fa[x];
}

void union_set(int x,int y)
{
    x = find_set(x);
    y = find_set(y);
    if(rk[x]>rk[y])
        fa[y] = x;
    else
    {
        fa[x] = y;
        if(rk[x]==rk[y])
            rk[y]++;
    }
}

int main()
{
    IO;
    init();
    cin>>n;
    for(int i=1; i<=n; i++)
        cin>>p[i].o.x>>p[i].o.y>>p[i].r;
    int e = 0,v = 0;
    vector<Point> all;
    for(int i=1; i<=n; i++)
    {
        vector<Point> tmp1;
        for(int j=1; j<=n; j++)
        {
            if(i==j)
                continue;
            vector<Point> tmp2 = p[i] & p[j]; ///求交点 返回交点
            if(tmp2.size())
                union_set(i,j); ///如果有交点 两个圆并进一个集里(为了求component)
            tmp1.insert(tmp1.end(),tmp2.begin(),tmp2.end()); ///求当前标号为i的圆上有几个交点就有几条边(e),边是一个圆一个圆求出来的
            all.insert(all.end(),tmp2.begin(),tmp2.end()); ///求总顶点数(v)
        }
        sort(tmp1.begin(),tmp1.end());
        e += unique(tmp1.begin(),tmp1.end()) - tmp1.begin();
    }
    sort(all.begin(),all.end());
    v = unique(all.begin(),all.end()) - all.begin();
    set<int> c;
    for(int i=1; i<=n; i++)
        c.insert(find_set(i)); ///求c
    cout<<e-v+c.size()+1<<endl;
    return 0;
}

为什么不是v-e+r = 2 见上图

f=e−v+c+1 ==》 v-e+f = c+1 好好好

 

D. A Creative Cutout

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

Everything red frightens Nian the monster. So do red paper and... you, red on Codeforces, potential or real.

Big Banban has got a piece of paper with endless lattice points, where lattice points form squares with the same area. His most favorite closed shape is the circle because of its beauty and simplicity. Once he had obtained this piece of paper, he prepares it for paper-cutting.

He drew n concentric circles on it and numbered these circles from 1 to n such that the center of each circle is the same lattice point and the radius of the k-th circle is  times the length of a lattice edge.

Define the degree of beauty of a lattice point as the summation of the indices of circles such that this lattice point is inside them, or on their bounds. Banban wanted to ask you the total degree of beauty of all the lattice points, but changed his mind.

Defining the total degree of beauty of all the lattice points on a piece of paper with n circles as f(n), you are asked to figure out .

Input

The first line contains one integer m (1 ≤ m ≤ 1012).

Output

In the first line print one integer representing .

Examples

input

Copy

5

output

Copy

387

input

Copy

233

output

Copy

788243189

Note

A piece of paper with 5 circles is shown in the following.

There are 5 types of lattice points where the degree of beauty of each red point is 1 + 2 + 3 + 4 + 5 = 15, the degree of beauty of each orange point is 2 + 3 + 4 + 5 = 14, the degree of beauty of each green point is 4 + 5 = 9, the degree of beauty of each blue point is 5 and the degree of beauty of each gray point is 0. Therefore, f(5) = 5·15 + 4·14 + 4·9 + 8·5 = 207.

Similarly, f(1) = 5, f(2) = 23, f(3) = 50, f(4) = 102 and consequently .

For the sake of explanation, let's use  to represent the binomial coefficient  and construct a coordinate system such that each coordinate axis parallels to one of the lattice edges, the origin is the center of concentric circles and each unit of length in this system is as long as the length of a lattice edge.

For f(n), we could figure out the contribution of each lattice point (x, y) is

利用该公式分离常数很重要 消去了k

Defining L as x2 + y2, we could conclude for the answer the contribution of each lattice point (x, y) is

which is a small-degree polynomial of L.

Tips: prove  with mathematical induction or others.

By using , we could form the answer as

where  is the coefficient calculated from the original polynomial.

The remaining part to solve this problem is just to enumerate all the possible integers x, q and then calculate  in constant time. The total complexity is .

By the way, the standard solution has hardcoded some closed forms to calculate the partial sum of small powers fast, but you can precalculate  and then enumerate x.

Please be careful with 64-bit integer overflow, for example, 1012·109 ≥ 264. Although there is a pretest in case of m = 232 to reject brute force and some solutions with obvious overflow, it is highly probable to fail in the case of large input such as m = 1012. The probability of failure is increasing when the number increases. Take care.

Bonus. Solve the problem with 1 ≤ m ≤ 1018.

https://www.cnblogs.com/wfj2048/p/8721454.html

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值