【NOIP2017提高A组冲刺11.6】项链
来源:互联网 发布:企业网络规划方案 编辑:程序博客网 时间:2024/05/17 23:52
Description
给一个n个点的环染m种颜色,有3种操作,分别为旋转、翻转和把所有颜色编号+1
如果两个方案在经过任意次操作之后等价了这两个方案就是等价的
求所有本质不同的染色方案数
n,m<=1e18,保证n,m逆元存在
Solution
burnside裸题,但是多了一个颜色操作
把颜色操作也视为置换,考虑他对经典的两种置换的影响
对于旋转,我们每一组的循环节长度为n/(i,n)
如果它在+把所有颜色d(0<=d< m)后能变回它自己它就是一个不动点
那么循环节种的每一个元素在模m意义下都比上一个元素大d
能变回原样就是n/(i,n)d≡ 0 mod m
经过一些简单的数论推导我们可以得出d有(m,n/(i,n))种取值
于是我们的旋转就变成了
同理可以发现翻转时我们只有当对称轴不经过点时会产生长度为2的循环节
于是翻转可以O(1)解决
考虑旋转的式子,枚举n的因数i
如果我们能对n分解质因数那么这道题就做完了
发现n可以达到10^18,于是我们需要用Pollard_Rho来分解
然后就做完了
Code
#include <cstdio>#include <cstring>#include <algorithm>#define fo(i,a,b) for(int i=a;i<=b;i++)using namespace std;typedef long long ll;const int Mo=998244353,S=3;ll mult(ll x,ll y,ll Mo) { x%=Mo;y%=Mo; ll tmp=(ll)((long double)x*y/Mo+1e-8)*Mo; return (x*y-tmp+Mo)%Mo;}ll pwr(ll x,ll y,ll Mo) { ll z=1;x%=Mo;y%=(Mo-1); for(;y;y>>=1,x=mult(x,x,Mo)) if (y&1) z=mult(z,x,Mo); return z;}ll gcd(ll x,ll y) { if (!x) return 1; if (x<0) return gcd(-x,y); return y?gcd(y,x%y):x;}ll n,m,ans,nn,mm,invm;ll pri[70],a[20];int tot,cnt,b[20],tmp;bool check(ll a,ll n,ll x,ll t) { ll res=pwr(a,x,n),lst=res; fo(i,1,t) { res=mult(res,res,n); if (res==1&&lst!=1&&lst!=n-1) return 1; lst=res; } if (res!=1) return 1; else return 0;} bool Miller_Rabin(ll n) { if (n<2) return 0; if (n==2) return 1; if (!(n&1)) return 0; ll x=n-1,t=0; while (!(x&1)) x>>=1,t++; fo(i,1,S) { ll a=rand()%(n-1)+1; if (check(a,n,x,t)) return 0; } return 1;}ll Pollard_rho(ll n,ll t) { int i=1,k=2; ll x0=rand()%n,y=x0; while (1) { i++; x0=(mult(x0,x0,n)+t)%n; ll d=gcd(y-x0,n); if(d!=1&&d!=n) return d; if(y==x0) return n; if(i==k) y=x0,k<<=1; tmp++; } }void find(ll n) { if (n==1) return; if (Miller_Rabin(n)) { pri[++tot]=n; return; } ll p=n;tmp=0; while (p>=n) p=Pollard_rho(p,rand()%(n-1)+1); printf("%d\n",tmp); find(p);find(n/p);}void dfs(int x,ll y,ll phi) { if (x>cnt) { (ans+=gcd(y,m)%Mo*pwr(m,n/y,Mo)%Mo*phi%Mo)%=Mo; return; } ll z=1,p=1; fo(i,0,b[x]) { dfs(x+1,y*z,phi*p%Mo); z=z*a[x]; if (i==0) p=p*(a[x]-1)%Mo; else p=p*a[x]%Mo; }}int ty;int main() { freopen("necklace.in","r",stdin); freopen("necklace.out","w",stdout); ll inv2=pwr(2,Mo-2,Mo);srand(233333); for(scanf("%d",&ty);ty;ty--) { scanf("%lld%lld",&n,&m); nn=n%Mo;mm=m%Mo; if (n&1) ans=pwr(m,n/2+1,Mo)*nn%Mo; else { if (m&1) ans=pwr(m,n/2,Mo)*nn%Mo*inv2%Mo; else ans=pwr(m,n/2,Mo)*nn%Mo; (ans+=pwr(m,n/2+1,Mo)*nn%Mo*inv2%Mo)%=Mo; } tot=cnt=0;find(n); sort(pri+1,pri+tot+1); fo(i,1,tot) if (pri[i]!=pri[i-1]) a[++cnt]=pri[i],b[cnt]=1; else b[cnt]++; dfs(1,1,1); ans=ans*pwr(nn*mm*2%Mo,Mo-2,Mo)%Mo; printf("%d\n",ans); }}
阅读全文
1 0
- 【NOIP2017提高A组冲刺11.6】项链
- JZOJ5457. 【NOIP2017提高A组冲刺11.6】项链
- [JZOJ5457]【NOIP2017提高A组冲刺11.6】项链
- 【NOIP2017提高A组冲刺11.6】总结
- [JZOJ5456]【NOIP2017提高A组冲刺11.6】奇怪的队列
- JZOJ 5455. 【NOIP2017提高A组冲刺11.6】拆网线
- Jzoj5455【NOIP2017提高A组冲刺11.6】拆网线
- Jzoj5456【NOIP2017提高A组冲刺11.6】奇怪的队列
- JZOJ5455. 【NOIP2017提高A组冲刺11.6】拆网线
- JZOJ5456. 【NOIP2017提高A组冲刺11.6】奇怪的队列
- 【NOIP2017提高A组冲刺11.1】总结
- 【NOIP2017提高A组冲刺11.2】总结
- 【NOIP2017提高A组冲刺11.3】总结
- 【NOIP2017提高A组冲刺11.4】总结
- 【NOIP2017提高A组冲刺11.1】荒诞
- 【NOIP2017提高A组冲刺11.2】失格
- 【NOIP2017提高A组冲刺11.5】轰炸
- 【NOIP2017提高A组冲刺11.5】总结
- X210核心板、底板原理图、数据手册导读
- 文件的概念
- 浅谈Ajax 工作原理
- win64下安装配置eclipse+MySQL+Tomcat
- mybatis一级缓存二级缓存
- 【NOIP2017提高A组冲刺11.6】项链
- 关于正向代理以及反向代理
- 设计模式(2)-抽象工厂模式(Abstract Factory)与生成器模式(Builder)模式
- HDOJ 1334 Perfect Cubes
- tensorflow GPU显存控制
- 线性代数之四:线性变换
- Spring定义bean的三种方式和自动注入
- MFC基于select模型的套接字类之服务器(6)
- windows核心编程之纤程