[COCI 2013/2014 ROUND 4] guma

分析:

可以用欧拉函数来解决。对于要将一个小矩形等分成n份,那么需要在1/n,2/n,3/n...(n-1)/n处各切一刀,将这n-1个分数化成最简分数后,分母的集合即时n的所有因数(不包括1),且分母与分子互质,那么对于某个分母b来说,一共会有φ(b)个,则等分成n份要切

∑φ(ai) (ai为n的因数,不包括1但包括n)

对于一个分母b如果之前被切过那么只需延长它即可,不用再切,这样我们就可以得到一个算法:

对于每个数找到它的所有因数,如果出现过就不管,没有出现过就把答案加上这个因数的欧拉函数值并把这个数标记为出现过,最后就能得到答案。

下面就是代码

 1 #include<cstdio>
 2 #include<cmath>
 3 #define maxn 100100
 4 #define LL long long
 5
 6 int Phi[maxn],divisor[maxn],f[maxn];
 7 int n,a,t,top;
 8 LL ans;
 9
10 void FindPhi()
11 {
12     int t,m;
13     Phi[1]=1;
14     for (int i=2;i<maxn;i++)
15     {
16         Phi[i]=i-1;
17         t=(int) sqrt(i);
18         for (int j=2;j<=t;j++)
19         {
20             m=i;
21             while (m%j==0) m/=j;
22             if (m==i) continue;
23             Phi[i]= (m==1)? i-i/j:Phi[m]*Phi[i/m];
24             break;
25         }
26     }
27 }
28
29 int main()
30 {
31     FindPhi();
32     scanf("%d",&n);
33     f[1]=1;
34     for (int j=0;j<=n;j++)
35     {
36         scanf("%d",&a);
37         top=0;
38         t=(int) sqrt(a);
39         for (int i=1;i<=t;i++) if (a%i==0)
40         {
41             divisor[++top]=i;
42             if (i!=a/i) divisor[++top]=a/i;
43         }
44         for (int i=1;i<=top;i++) if (!f[divisor[i]])
45         {
46             ans+=Phi[divisor[i]];
47             f[divisor[i]]=1;
48         }
49     }
50     printf("%I64d\n",ans);
51     return 0;
52 }
时间: 2024-10-13 19:16:06

[COCI 2013/2014 ROUND 4] guma的相关文章

[COCI 2013/2014 ROUND 5] ladice

分析:对于一个物品,只有两个抽屉A,B可以放,那么如果能够放下,那么一定是放在其中一个,设放在A中,那么以后可以且只能将其移动到B中,所以我们建一条有向边由A指向B,这样处理下去我们会发现对于每一条有向边一定是有物品的抽屉指向没有物品的抽屉,那么我们定义一个块为之间有边的点的集合,定义块的根为块中没有出边的点,那么一个块中只有根会是空的抽屉其他的一定是有物品的抽屉,那么每一个块就可以用一个并查集维护起来,每加一个物品(即加一条边)时,对于两个端点A,B,如果有A所在的并查集的根可以放那么就将A所

[COCI 2013/2014 ROUND 6] hash

分析: 很容易想到时间复杂度为O(26n)的暴力枚举算法,但由于n<=10,很明显会超时,这时会有一个比较常用的方法:折半枚举. 分别枚举前半段和后半段,把满足条件的结合起来就是答案. 对于f[i]=((f[i-1]*33) xor letter[i]) mod 2m 前半段很好做,直接带入公式,定义g[i]为hash值为i的个数,进行记录 后半段可以这样做: 在此题的背景下,因为m>=6,且1<=letter[i]<=26,所以 (a xor b) mod 2m=(a mod 2

[COCI 2013/2014 ROUND 6] graskrizja

分析: 这个题可以用分治的方法解决 先将所有的点按x坐标排序,以最中间的那个点的x坐标为轴,两边所有的点在轴上的对应的点加上,然后分别以同样的方法处理左右两个区间的点,递归处理下去知道区间只有一个点 下面是代码: 1 #include<cstdio> 2 #include<algorithm> 3 #define maxn 50100 4 using namespace std; 5 6 class Point 7 { 8 public: 9 int x,y; 10 void ge

2012 2013 2014 2015 Skype for Business MVP-变迁

2005年,初识Live Communications Server 2003 2008年,相识Office Communication Server (OCS) 2007 2010年,相知Lync Server 2010 2012年,相恋Lync Server 2013 2015年,告别Skype for Business Server 2015 或许,我应该走了,不是您不好! 为您付出够多,但还是得离开! 不是吗? 2012 2013 2014 2015 从Lync MVP到Skype fo

TCO 2014 Round 1C 概率DP

TCO round 1C的 250 和500 的题目都太脑残了,不说了. TCO round 1C 950 一个棋子,每次等概率的向左向右移动,然后走n步之后,期望cover的区域大小?求cover,肯定就是dp[l][r][n], 走了n步之后,左边cover了l,右边cover了r. 一开始DP没有搞清楚,这个要画一下图就更清楚了. 转移方程就是概率的传递方向. 1: double dp[505][505][2]; // l,r,n steps unsed; 2: class RedPain

Coder-Strike 2014 - Round 2

t题目链接:Coder-Strike 2014 - Round 2 A题:简单水题,注意能加入反复的数字.因此仅仅要推断是否能把Min和Max加入好.就能够了 B题:开一个sum计算每一个聊天总和,和一个s计算每一个人在每一个聊天总和,最后每一个人就用总和减掉自己发送的就可以 C题:最优策略为先把非特殊的答完,然后从最大的開始答 D题:dp,状态为dp[i][j][k],i表示当前长度,j表示前面数字的总和,k表示是否能组成,然后进行记忆化搜索 代码: A: #include <stdio.h>

2013·2014,赤脚跑步的日子

2013·2014,赤脚跑步的日子 开始跑步是在2012年年底,最初只想着每天跑跑步,锻炼下身体,没想到一跑就跑了很远的距离. 2012年上海马拉松举办的当天,我作为一个路人围观了一群快乐的疯子在风雨中奔跑,其中不乏年轻和年老的面庞,于是心生一念,我能否也成为其中一员,体验雨中奔跑的快乐.2012年上海马拉松当天,我决定开始了自己第一个半程马拉松的计划,用三个月的时间让自己从跑个三五公里就累得气喘吁吁到可以成功跑完一个21.0975km的距离,我也成为一个快乐奔跑的疯子. 往后的日子,每天都会坚

MyEclipse 10, 2013, 2014 破解、注册码

MyEclipse 试用期限一般是三十天,过了三十天后 MyEclipse 会提示用户注册而不能正常使用,这里分享一下破解过程,仅供学习和参考.MyEclipse 10, 2013, 2014 破解过程都是一致的,破解软件也是一致的. 破解压缩包下载地址: http://pan.baidu.com/s/1c0D7tio#path=%252FMyEclipse%252FMyEclipse%252010 https://i.cnblogs.com/Files.aspx(本博客的下载路径) 工具/原料

Google Code Jam 2014 Round 2回顾和分析

回顾 比赛开始网络就一直在抽风,不知道宿舍网渣还是有人攻击服务器.刷了n遍n久刷出了题目.提交A小case的时候眼睁睁看着时间过去,却提交不上,这破网.最后A题B题还是解决了,C题扫了一眼,读都没读,就奔D题去了,因为我看到了熟悉的trie这个单词,加之看到小case只有9分,判断小case应该比较容易.前面因为网络浪费了很多时间,加之从未编过trie的程序,只能临时上网翻书去学,最后D小这个可以很容易暴力解的问题也没编完. 最终的rank是13xx,考虑到在这次GCJ之前从未接触过编程竞赛,而