CF1208G Polygons 数论
题目链接:https://codeforces.com/contest/1208/problem/G
题意:给定两个正整数\(n\)和\(k\),询问在一个圆上你最少需要几个点,才能在这些点上构造出\(k\)个边数小于等于\(n\)的正多边形。
分析:我们假设我们选取了一个正\(m\)边形,那么边数为\(m\)的因子的所有正多边形也就全部满足了。因此如果我们选了正\(m\)边形,我们相当于已经选择了所有正\(p\)边形(\(p | k\))(比如说我们想要选正六边形,那么必须先选择正三角形),增加的点数即为\(\varphi (m)\)。因此我们只需要对欧拉函数排序,并将前\(k\)个累加即可。
upd:官方答案的证明方法可能更好。我们在选正多边形时,可以使每一个正多边形的第一个点重合。那么正\(m\)边形的每一个点在圆上的位置就可以表示为\(0, \frac{1}{m} , \frac{2}{m} , ... , \frac{m-1}{m}\)。因此在选择了\(k\)个正多边形后,最简真分数的总数即为我们要求的答案。于是只需要将我们选择的\(k\)个正多边形的欧拉函数累加即为答案,因为欧拉函数就是互质数数量,也就是新增加的点数。
AC代码:
#include <bits/stdc++.h>
#define rep(i, a, b) for(long long i = a; i <= b; ++i)
using namespace std;
void io() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
}
long long ans = 2;
const int maxn = 1000000;
bool vis[maxn + 5];
int prime[maxn + 5], phi[maxn + 5], n, k, cnt;
void Phi() {
phi[1] = 1; vis[1] = true;
for (int i = 2; i <= maxn; i++) {
if (!vis[i]) prime[cnt++] = i, phi[i] = i - 1;
for (int j = 0; j < cnt&&prime[j] * i <= maxn; j++) {
vis[prime[j] * i] = 1;
if (i%prime[j] == 0) {
phi[i*prime[j]] = phi[i] * prime[j];
break;
}
phi[i*prime[j]] = phi[i] * (prime[j] - 1);
}
}
}
vector<int> v;
int main() {
io(); cin >> n >> k;
if (k == 1) { cout << 3; return 0; }
Phi();
rep(i, 3, n) v.emplace_back(phi[i]);
sort(v.begin(), v.end());
rep(i, 0, k - 1) ans += v[i];
cout << ans;
}
CF1208G Polygons 数论的更多相关文章
- Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2) G. Polygons 数论
G. Polygons Description You are given two integers
- cf1208G Polygons 欧拉函数
链接 cf 给你两个正整数\(n\)和\(k\),询问在一个圆上你最少需要几个点构才能造出\(k\)个边数小于等于\(n\)的正多边形 思路 深受迫害,所以写的详细一点,不会请留言. 性质1 考虑加进 ...
- 「CF1208G」 Polygons
「CF1208G」 Polygons 似乎我校神犇在很久以前和我提过这题? 首先有一点显而易见:这 \(k\) 个多边形肯定至少有一个公共的顶点.假设我们将此点定义为起点. 那么对于一个正 \(n\) ...
- Codeforces Round #382 Div. 2【数论】
C. Tennis Championship(递推,斐波那契) 题意:n个人比赛,淘汰制,要求进行比赛双方的胜场数之差小于等于1.问冠军最多能打多少场比赛.题解:因为n太大,感觉是个构造.写写小数据, ...
- NOIP2014 uoj20解方程 数论(同余)
又是数论题 Q&A Q:你TM做数论上瘾了吗 A:没办法我数论太差了,得多练(shui)啊 题意 题目描述 已知多项式方程: a0+a1x+a2x^2+..+anx^n=0 求这个方程在[1, ...
- 数论学习笔记之解线性方程 a*x + b*y = gcd(a,b)
~>>_<<~ 咳咳!!!今天写此笔记,以防他日老年痴呆后不会解方程了!!! Begin ! ~1~, 首先呢,就看到了一个 gcd(a,b),这是什么鬼玩意呢?什么鬼玩意并不 ...
- hdu 1299 Diophantus of Alexandria (数论)
Diophantus of Alexandria Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java ...
- 【BZOJ-4522】密钥破解 数论 + 模拟 ( Pollard_Rho分解 + Exgcd求逆元 + 快速幂 + 快速乘)
4522: [Cqoi2016]密钥破解 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 290 Solved: 148[Submit][Status ...
- bzoj2219: 数论之神
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #i ...
随机推荐
- google protocol 入门 demo
ubunbu系统下google protobuf的安装 说明: 使用protobuf时需要安装两部分: 第一部分为*.proto文件的编译器,它负责把定义的*.proto文件生成对应的c++类的.h和 ...
- JS高级---沙箱小案例
沙箱小案例 substr截取, 从指定的字段开始截取 (function () { var str="小白喜欢小黑"; str=str.substr(2); console.log ...
- pytest学习5-mark用例分类
使用Mark标记测试用例 通过使用pytest.mark你可以轻松地在测试用例上设置元数据.例如, 一些常用的内置标记: skip - 始终跳过该测试用例 skipif - 遇到特定情况跳过该测试用例 ...
- 怎么编写API和或者自己不属于知识小案例demo程序
再使用一个函数,进行测试的调用,然后进行调用这样就不需要再为makefile什么,还有就是改什么鬼东西烦恼了. 然后把需要的功能进行分解就行了.
- python定义一种新类型的元组
# 定义一种新类型的元组,只保留int类型,切只大于0的元素 # 例如:IntTuple([1,-1,"abc",6,['x','y'],3])==>(1,6,3) # 解决 ...
- 剑指offer 面试题. 滑动窗口的最大值
题目描述 给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值.例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6 ...
- HTTPSConnectionPool(host='files.pythonhosted.org', port=443): Read timed out的解决方法
问题描述: Pycharm创建Django项目提示:HTTPSConnectionPool(host='files.pythonhosted.org', port=443): Read timed o ...
- 菜单制作:ul li横向排列
CSS菜单制作 <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...
- Python入门2 —— 变量
一:问号三连 1.什么是变量? 变 指的是事物的状态是可以发生变化的 量 指的是记录事物的状态 2.为什么要有变量? 为了让计算机像人一样去记录事物的状态 3.怎么用变量? 先定义 后引用 二:变量的 ...
- AcWing 845. 八数码
https://www.acwing.com/problem/content/847/ #include<bits/stdc++.h> using namespace std; int b ...