SPOJ422:Transposing is Even More Fun(Polya)
来源:互联网 发布:软件研发部门规划 编辑:程序博客网 时间:2024/06/11 00:14
传送门
题意:
给你一个
的……每行也是从左到右存放。现在你想求它的转置矩阵(也是一样的储存方
式),但是只能用交换操作,问需要交换多少步。
题解:
直接贴论文了:
为了描述方便起见,先看一个例子:假设 a=5, b=3。那么考虑元素(12,1),用二进制表示是(01010,001),那么它原来的地址就是 01010 001,而新的地址就是 001 01010。可见这个转置操作其实就是把每个元素的地址循环向右移动了
b 位。
考虑地址的循环节如果有k 个,那么答案就是2a+b−k 。
问题转化为求地址的循环节,显然,两个地址若能通过右移b的某倍数步,那么他们处于一个循环。
相当于是求在右移b的倍数步这个置换群中找染色方案。
成功转化为
考虑线筛的时候记录最小质因数,这样找出一个大数的所有质因数接近
#include<iostream>#include<cstdio>#include<vector>using namespace std;struct IO{ streambuf *ib,*ob; inline void init(){ ios::sync_with_stdio(false); cin.tie(NULL);cout.tie(NULL); ib=cin.rdbuf();ob=cout.rdbuf(); } inline int read(){ static char ch;static int i,f; ch=ib->sbumpc();i=0,f=1; while(!isdigit(ch)){ if(ch==-1)return false; if(ch=='-')f=-1; ch=ib->sbumpc(); } while(isdigit(ch)){ i=(i+(i<<2)<<1)+ch-'0'; ch=ib->sbumpc(); } return ((f>0)?i:-i); } inline void W(int x){ static int buf[50]; if(!x){ob->sputc('0');return;} if(x<0){ob->sputc('-');x=-x;} while(x){buf[++buf[0]]=x%10;x/=10;} while(buf[0]){ob->sputc(buf[buf[0]--]+'0');} }}io;const int Mod=1e6+3;inline int gcd(int x,int y){return (y?(gcd(y,x%y)):x);}const int Maxn=1e6;int ans,Primecnt,prime[Maxn+50],phi[Maxn+50],IsNotPrime[Maxn+50],_pow[Maxn],inv[Maxn],pr[Maxn];inline void seive(){ phi[1]=1;inv[1]=1;_pow[1]=2;pr[1]=1; for(int i=2;i<=Maxn;i++){ _pow[i]=(_pow[i-1]<<1)%Mod; inv[i]=(-1ll*inv[Mod%i]*(Mod/i))%Mod; if(!IsNotPrime[i]){prime[++Primecnt]=i;phi[i]=i-1;pr[i]=i;} for(int j=1;j<=Primecnt;j++){ int k=i*prime[j]; if(k>Maxn)break; IsNotPrime[k]=1; if(!(i%prime[j])){phi[k]=phi[i]*prime[j];pr[k]=pr[i];break;} phi[k]=phi[i]*(prime[j]-1);pr[k]=prime[j]; } }}int a,b,lim,g,factory[Maxn],cnt[Maxn],tail;inline void fac(int x){ tail=0;int last=0; while(pr[x]!=1){ if(pr[x]==last)cnt[tail]++; else cnt[++tail]=1,factory[tail]=pr[x],last=pr[x]; x/=pr[x]; }}inline void dfs(int pos,int d){ if(pos>tail){(ans+=1ll*phi[lim/d]*_pow[d*g]%Mod)%=Mod;return;} dfs(pos+1,d); for(int i=1;i<=cnt[pos];i++)d*=factory[pos],dfs(pos+1,d);}int main(){ io.init();seive(); int T=io.read(); while(T--){ ans=0; a=io.read(),b=io.read(); if(a==0||b==0){io.W(0);io.ob->sputc('\n');continue;} g=gcd(a+b,b),lim=(a+b)/g; fac(lim);dfs(1,1); ans=1ll*ans*inv[lim]%Mod; ans=(_pow[a+b]-ans+Mod)%Mod; io.W(ans);io.ob->sputc('\n'); }}
阅读全文
0 0
- SPOJ422:Transposing is Even More Fun(Polya)
- SPOJ 422 Transposing is Even More Fun(Polya计数)
- [spoj244]Transposing is Even More Fun 解题报告
- 【SPOJ-TRANSP2】Transposing is Even More Fun【Pólya】【欧拉函数】【二进制】
- 【SPOJ-TRANSP】Transposing is Fun【Pólya】【欧拉函数】【二进制】
- Making Sequences is Fun(简单枚举)
- To live a life a bit longer and even more desirable, that discipline is without a doubt sharp: Reall
- Programming is fun
- Dog eating is fun
- Machine Learning is Fun!
- Counting Kangaroos is Fun
- Coding,coding and even more coding
- Codeforces Round #219 (Div. 2) Counting Kangaroos is Fun
- CF372C Watching Fireworks is Fun(dp+双端队列)
- 【CodeForces】373C - Counting Kangaroos is Fun(二分)
- CodeForces 372A Counting Kangaroos is Fun (二分)
- coderforces 372A Counting Kangaroos is Fun(二分)
- Codeforces 373C:Counting Kangaroos is Fun(二分+贪心)
- 训练fater rcnn时出现path not exist问题
- 关于"XML 文档(2, 2)中有错误:不应有 <xml xmlns=''>"错误
- 欢迎使用CSDN-markdown编辑器
- dp动态规划分类详解
- gdb调试多线程
- SPOJ422:Transposing is Even More Fun(Polya)
- Selenium学习四——利用Python爬取网页多个页面的表格数据并存到已有的excel中
- JSP中相对路径与绝对路径问题
- HDU 4272 LianLianKan
- 高并发系统限流
- OTT系统和IPTV系统不一样吗?有什么区别?
- 关于字符串
- 关于项目的一点点总结,签到返利日历的实现
- CAN通信中地址设置的问题