bzoj5193 [Usaco2018 Feb]Cow Gymnasts

网友投稿 296 2022-09-02

bzoj5193 [Usaco2018 Feb]Cow Gymnasts

​​ Description

厌倦了农场生活,奶牛们变卖了所有尘世的财产,加入了一支巡回马戏团。到现在为止,奶牛们已经能够进行简单 的表演了:耍火把、走钢丝、骑独轮车——没什么是拥有灵巧蹄子的奶牛做不到的。但是,马戏团指挥想要为他们 的下一次演出创作一个更加激动人心的表演。新的表演所用的舞台由N个围成一圈的平台组成。在每个平台上,1至 N头奶牛叠成一摞,一头叠在一头上面。当指挥给出信号的时候,每摞奶牛同时顺时针落下,最下面的奶牛不动, 在她上面的奶牛顺时针移动一个平台,再上面的奶牛顺时针移动两个平台,等等。作为技艺高超的体操家,奶牛们 明白她们在这个表演的技术方面没有任何问题。不同摞的奶牛在下落的过程中不会相互“干扰”,所以每头奶牛都 会落在预期的平台上。然后所有落在同一平台上的奶牛又会重新叠成一摞,这次她们不会再落下来。指挥认为,如 果在奶牛们落下之后,每个平台上新的那一摞奶牛的数量和原来这个平台上的那一摞奶牛数量相等的话,这次表演 就会格外激动人心。我们把满足这种性质的各摞奶牛的数量排列称为是“魔幻的”。请帮助奶牛计算魔幻的排列数 。由于这个数字可能非常大,计算该数mod 10^9+7的余数。两个排列被认为是不同的,如果这两个排列在任何一个 平台上分配了不同数量的奶牛。

Input

输入包含一个整数N(1≤N≤10^12)。

Output

输出一个整数,为魔幻的排列数mod 10^9+7的余数。

Sample Input

4 Sample Output

6 当N=4时,魔幻的排列有(1,1,1,1),(2,2,2,2),(3,3,3,3), (4,4,4,4),(2,3,2,3),以及(3,2,3,2)。 HINT

Source

Platinum ​​ 假设台上最少的牛只有m只并且记当前台为i j≡i(modg) j ≡ i ( mod g ) ,g=gcd(N,m) g = gcd ( N , m ) 台子上所有的牛也必定是m只 其他台子上的牛是m+1只 怎么证明的就是考虑周期性 每一个对其他的影响这样重复算的 为什么是gcd(n,m) 可以考虑为是小循环和大循环多少次之后可以重复 那么答案便是 ANS=1−2N+∑Nm=12gcd(m,N) A N S = 1 − 2 N + ∑ m = 1 N 2 gcd ( m , N ) m=n的情况单独计算所以1-2^n 考虑枚举g ANS=1−2N+∑g∣N2gφ(Ng). A N S = 1 − 2 N + ∑ g ∣ N 2 g φ ( N g ) . φ(x=pe11pe22⋯peii)=x∗(p1−1)(p2−1)⋯(pi−1)p1p2⋯pi. φ ( x = p 1 e 1 p 2 e 2 ⋯ p i e i ) = x ∗ ( p 1 − 1 ) ( p 2 − 1 ) ⋯ ( p i − 1 ) p 1 p 2 ⋯ p i . 枚举的时候更改了一下顺序 就变成我去枚举φ φ 里面的东西 那么可以知道这样枚举的话我只需要 如果g不增加 φ φ 里也不增加否则 增加质因子之后g同样需要枚举着增加

#include#include#include#define ll long long#define mod 1000000007using namespace std;inline char gc(){ static char now[1<<16],*S,*T; if (T==S){T=(S=now)+fread(now,1,1<<16,stdin);if (T==S) return EOF;} return *S++;}inline ll read(){ ll x=0,f=1;char ch=gc(); while(ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=gc();} while(ch<='9'&&ch>='0') x=x*10+ch-'0',ch=gc(); return x*f;}inline ll pow(ll base,ll t){ ll tmp=1; for (;t;t>>=1,(base*=base)%=mod) if (t&1) (tmp*=base)%=mod;return tmp;}vectorprime;vector nm;ll n,ans;inline void dfs(int x,ll g,ll up,ll down){ if (x==prime.size()){ if (g==1) return;// m=n的情况单独计算 ans+=pow(2,n/g)*((g/down*up)%mod)%mod;ans%=mod;return; }dfs(x+1,g,up,down);up*=(prime[x]-1);down*=prime[x]; for (int i=1;i<=nm[x];++i) g*=prime[x],dfs(x+1,g,up,down);}int main(){ freopen("gymnasts.in","r",stdin); freopen("gymnasts.out","w",stdout); n=read();ll x=n; for (int i=2;(ll)i*i<=n;++i){int tmp=0; if (x%i) continue;prime.push_back(i); while(x%i==0) ++tmp,x/=i;nm.push_back(tmp); }if (x>1) prime.push_back(x),nm.push_back(1); dfs(0,1,1,1);ans-=(n-1)%mod;(ans+=1+mod)%=mod; printf("%lld\n",ans); return 0;}

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:浅谈mysql集群
下一篇:bzoj1095 [ZJOI2007]Hide 捉迷藏 括号序列/动态点分治/树的数据生成
相关文章

 发表评论

暂时没有评论,来抢沙发吧~