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 x, y 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 x, y 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