题意

传送门

题解

首先我们不竖着看奶牛而是横着看。从下往上把奶牛叫做处于第0,1,2...0,1,2...0,1,2...层。那么相当于第000层的不动,第111层的平移一格,第222层的平移222格,以此类推,第iii层平移iii格。假设每一层的最小正周期为xix_ixi​,则显然有xi∣ix_i|ixi​∣i且xi∣nx_i|nxi​∣n。因为第iii层动了iii步恰好复原,iii就一定是最小正周期的倍数;因为是nnn的环排列,所以最小正周期是nnn的因数。

那么就有xi∣gcd(i,n)x_i|gcd(i,n)xi​∣gcd(i,n),又因为iii与i−1i-1i−1互质,则gcd(i,n)gcd(i,n)gcd(i,n)与gcd(i−1,n)gcd(i-1,n)gcd(i−1,n)互质,所以xix_ixi​与xi−1x_{i-1}xi−1​互质。

又因为为了不让第iii层的奶牛悬空,有第iii层的位置移动后必有第i−1i-1i−1层的奶牛支撑,结合互质得到,在xix_{i}xi​存在的情况下,xi−1=1x_{i-1}=1xi−1​=1。

意思就是说除了最上面一层,下面其它层周期均为111,也就是全都占满了,每一层都是nnn头奶牛。那么这个序列最多只能出现两个值,iii和i−1i-1i−1。

我们枚举iii,最大周期是gcd(i,n)gcd(i,n)gcd(i,n),答案就是

1+∑i=1n−1(2gcd(i,n)−1)=(∑i=1n−12gcd(i,n))−(n−2)\large1+\sum_{i=1}^{n-1}\left(2^{gcd(i,n)}-1\right)=\left(\sum_{i=1}^{n-1}2^{gcd(i,n)}\right)-(n-2)1+i=1∑n−1​(2gcd(i,n)−1)=⎝⎛​i=1∑n−1​2gcd(i,n)⎠⎞​−(n−2)前面的111表示最高层是第000层,后面的表示在gcd(i,n)gcd(i,n)gcd(i,n)这一最大周期内每个值只有iii和i−1i-1i−1两种取法,所以是222的次幂,不是最大周期的情况也能包括在内。后面的111表示不能全是i−1i-1i−1,否则最高层就不是iii了。

暴力做是O(nlogn)O(nlogn)O(nlogn)的,要考虑优化。

将gcd(i,n)gcd(i,n)gcd(i,n)相等的一起处理,对于1≤x&lt;n1\le x&lt;n1≤x<n,gcd(i,n)=x(1≤i&lt;n)gcd(i,n)=x(1\le i&lt;n)gcd(i,n)=x(1≤i<n)的iii的数量为φ(n/i)φ(n/i)φ(n/i),显然。所以答案就是(∑x∣nn−12x⋅φ(n/x))−(n−2)\left(\sum_{x|n}^{n-1}2^x\cdot φ(n/x)\right)-(n-2)⎝⎛​x∣n∑n−1​2x⋅φ(n/x)⎠⎞​−(n−2)

那么搜索出所有的因数,搜索过程中可以算出φ(n/x)φ(n/x)φ(n/x),最后时间复杂度为O(n⋅logn)O(\sqrt n\cdot logn)O(n​⋅logn)。logloglog是快速幂。

CODE

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int mod = 1000000007;
LL p[20], k[20], ans, a[20][40], n;
//p[i]表示第i个质因数,k[i]表示p[i]的幂
//a[i][j] = p[i]^j int cnt;
inline LL qpow(LL a, LL b) {
LL re=1;
for(;b;b>>=1,a=a*a%mod)if(b&1)re=re*a%mod;
return re;
}
void dfs(int i, LL x, LL phi) {
if(i > cnt) {
if(x < n)
ans = (ans + 1ll * qpow(2, x) * phi % mod) % mod;
return;
}
for(int j = 0; j <= k[i]; ++j)
dfs(i+1, x*a[i][j], phi/a[i][j]/(j<k[i]?p[i]:1)*(j<k[i]?p[i]-1:1)); //计算phi(n/x)
}
int main () {
scanf("%lld", &n); LL N = n;
for(LL i = 2; i*i <= n; ++i)
if(n % i == 0) {
p[++cnt] = i;
a[cnt][0] = 1;
while(n % i == 0) {
n /= i, ++k[cnt];
a[cnt][k[cnt]] = a[cnt][k[cnt]-1] * i;
}
}
if(n > 1) p[++cnt] = n, k[cnt] = 1, a[cnt][0] = 1, a[cnt][1] = n;
n = N;
dfs(1, 1, n);
printf("%lld\n", ((ans - n + 2) % mod + mod) % mod); //记得加mod
}

事实上官方题解是这样子的 Here

Luogu P4270 [USACO18FEB]Cow Gymnasts (打表找规律)的更多相关文章

  1. hdu 3032 Nim or not Nim? (SG函数博弈+打表找规律)

    Nim or not Nim? Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Sub ...

  2. HDU 5753 Permutation Bo (推导 or 打表找规律)

    Permutation Bo 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5753 Description There are two sequen ...

  3. HDU 4861 Couple doubi (数论 or 打表找规律)

    Couple doubi 题目链接: http://acm.hust.edu.cn/vjudge/contest/121334#problem/D Description DouBiXp has a ...

  4. HDU2149-Good Luck in CET-4 Everybody!(博弈,打表找规律)

    Good Luck in CET-4 Everybody! Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ...

  5. 【ZOJ】3785 What day is that day? ——浅谈KMP在ACM竞赛中的暴力打表找规律中的应用

    转载请声明出处:http://www.cnblogs.com/kevince/p/3887827.html    ——By Kevince 首先声明一下,这里的规律指的是循环,即找到最小循环周期. 这 ...

  6. HDU 5795 A Simple Nim(SG打表找规律)

    SG打表找规律 HDU 5795 题目连接 #include<iostream> #include<cstdio> #include<cmath> #include ...

  7. hdu_5894_hannnnah_j’s Biological Test(打表找规律)

    题目链接:hdu_5894_hannnnah_j’s Biological Test 题意: 有n个不同的位置围成一个圈,现在要安排m个人坐,每个人至少的间隔为k,问有多少种安排 题解: 先打表找规律 ...

  8. hdu_5795_A Simple Nim(打表找规律的博弈)

    题目链接:hdu_5795_A Simple Nim 题意: 有N堆石子,你可以取每堆的1-m个,也可以将这堆石子分成3堆,问你先手输还是赢 题解: 打表找规律可得: sg[0]=0 当x=8k+7时 ...

  9. hdu_5793_A Boring Question(打表找规律)

    题目链接:hdu_5793_A Boring Question 题意: 自己看吧,说不清楚了. 题解: 打表找规律 #include<cstdio> typedef long long l ...

随机推荐

  1. golang中switch用法细节

    1. switch穿透-fallthrough, 如果在case语句块后增加fallthrough,则会继续执行下一个case,也叫switch穿透,默认只穿透一层 2. Type Switch: s ...

  2. 导出excel的功能效果实现

    <el-button @click="exportExcel" > <i style="display: inline-block;"> ...

  3. SAS学习笔记11 SAS宏

    宏是一个被储存的文本,用一个名字识别它.最简单的宏就像一个宏变量一样工作,但复杂的宏可以完成许多宏变量不能做的事. 定义宏的语句格式为: %macro 宏名称: 宏文本 %mend <宏名称&g ...

  4. diverta 2019 Programming Contest

    A:签到. #include<bits/stdc++.h> using namespace std; #define ll long long #define inf 1000000010 ...

  5. (十一)web服务与javaweb结合(2)

    一.解决问题及解决方法 解决问题:上章节用监听器的方式是有缺陷的:web服务的端口和web工程的端口不能一致. 解决方案:将webService绑定到web工程中,使得共用一个端口. 二.案例 2.1 ...

  6. Docker 安装mysql5.6

    1.首先进入命令行现在mysql5.6镜像 E:\>docker pull mysql:5.6 2.把mysql的配置文件放入到本地,供后期做修改用 文件分别为:mysql.cnf 和 mysq ...

  7. kong命令(三)route

    介绍 route 是一套匹配客户端请求的规则.每个route都会匹配一个service,每个service可定关联多个route. 可以说service:route=1:n.一对多的关系.每个匹配到r ...

  8. sql 添加变量

    在sql语句中添加变量. declare @local_variable data_type 声明时需要指定变量的类型, 可以使用set和select对变量进行赋值, 在sql语句中就可以使用@loc ...

  9. javaweb常识

    Tomcat下载地址www.apache.org 在电脑中查看java版本:cmd中输入java -version tomcat解压后目录 bin:放可执行文件(如startup.bat   shut ...

  10. java轻松玩转localdatetime

    废话不多说,直接上代码 //时间戳转LocalDateTime public static LocalDateTime getLocalDateTime(long timestamp) { Insta ...