【SPOJ】Transposing is even more fun!
题意:
给出a、b 表示按先行后列的方式储存矩阵 现在要将其转置 可以交换两个点的位置 求最小操作次数
题解:
储存可以将其视为拉成一条链 设a=5、b=2 则在链上坐标用2^***(a,b)表示为(xxxxxyy) 转置后为(yyxxxxx)
这时将其视为另一个点的坐标 继续转置为(xxyyxxx)... 直到再变成(xxxxxyy)这样每次循环可以节省1次转置 所以ans=2^(a+b)-k k为循环的个数
k的计算:右移b位 右移b*2位 右移b*3位... 构成了一个置换群 置换个数为(a+b)/***(a,b)
因为它是循环的 所以向右移bx位 可视为右移bx%(a+b)位 设bx=z(mod (a+b))
该方程有解条件为***(b,(a+b))|z -> ***(a,b)|z 所以z为***(a,b)的倍数
k的值可理解为将长度为(a+b)/***(a,b)的串 染成2^***(a,b)种颜色(循环移动视为同种方案) 的方案数
既为poj2154的题目
因为spoj会卡常数 这题很容易TLE 我做了几个优化:
1.记忆化欧拉函数 将算过的欧拉函数存下来 下次直接用
2.预处理幂 可以发现这题要用的幂都是2^x 可以直接预处理出来
3.dfs n的因数 枚举m的因数会浪费很多时间 可以先算出n的质因数 在通过dfs算出其因数
4.尽量不要用long long 在会超int的地方强制转换一下就行
这题时限是8s 我跑了4.2s 目测前面T了十几次
代码:
#include <cstdio>
#define _(x) static_cast<long long>(x)
const int mo=;
typedef int ll;
ll t,a,b,n,m,g,phii[],primer[],np,flag[],pow[],ans,p[],nn;
void makep(ll t){
for (int i=;i<=np && t> && primer[i]*primer[i]<=t;i++)
if (t%primer[i]==){
p[++nn]=primer[i];
while (t%primer[i]==) t/=primer[i];
}
if (t>) p[++nn]=t;
}
ll phi(ll t){
ll out=,tt=t;
if (phii[t]) return phii[t];
for (int i=;i<=np && t> && primer[i]*primer[i]<=t;i++)
if (t%primer[i]==){
t/=primer[i];
out=_(out)*_((primer[i]-))%mo;
while (t%primer[i]==) t/=primer[i],out=_(out)*_(primer[i])%mo;
}
if (t>) out=_(out)*_((t-))%mo;
return phii[tt]=out;
}
void dfs(ll now,ll sum){
if (now>nn){
ans=(ans+_(phi(n/sum))*_(pow[sum*g]))%mo;
return;
}
for (ll i=;n%i==;i*=p[now]) dfs(now+,sum*i);
}
void extgcd(ll a,ll b,ll &x,ll &y){
if (!b) x=,y=;
else{
extgcd(b,a%b,x,y);
ll t=x;
x=y;
y=t-a/b*y;
}
}
ll gcd(ll a,ll b){
while (b) b^=a^=b^=a%=b;
return a;
}
ll work(){
if (!a || !b) return ;
ll x,y;
g=gcd(a,b);
n=(a+b)/g;
nn=ans=;
makep(n);
dfs(,);
extgcd(n,mo,x,y);
x=(x%mo+mo)%mo;
ans=(_(ans)*_(x))%mo;
return ((pow[a+b]-ans)%mo+mo)%mo;
}
void makepr(){
for (int i=;i<=;i++){
if (!flag[i]) primer[++np]=i;
for (int j=;j<=np && primer[j]*i<=;j++){
flag[primer[j]*i]=;
if (i%primer[j]==) break;
}
}
pow[]=;
for (int i=;i<=;i++) pow[i]=(pow[i-]*)%mo;
}
int main(){
freopen("spoj442.in","r",stdin);
freopen("spoj442.out","w",stdout);
scanf("%d\n",&t);
makepr();
while (t--){
if (t==){
t=;
}
scanf("%d%d\n",&a,&b);
printf("%d\n",work());
}
fclose(stdin);
fclose(stdout);
}
【SPOJ】Transposing is even more fun!的更多相关文章
- 【SPOJ】NUMOFPAL - Number of Palindromes(Manacher,回文树)
[SPOJ]NUMOFPAL - Number of Palindromes(Manacher,回文树) 题面 洛谷 求一个串中包含几个回文串 题解 Manacher傻逼题 只是用回文树写写而已.. ...
- 【SPOJ】Substrings(后缀自动机)
[SPOJ]Substrings(后缀自动机) 题面 Vjudge 题意:给定一个长度为\(len\)的串,求出长度为1~len的子串中,出现最多的出现了多少次 题解 出现次数很好处理,就是\(rig ...
- 【SPOJ】Longest Common Substring II (后缀自动机)
[SPOJ]Longest Common Substring II (后缀自动机) 题面 Vjudge 题意:求若干个串的最长公共子串 题解 对于某一个串构建\(SAM\) 每个串依次进行匹配 同时记 ...
- 【SPOJ】Longest Common Substring(后缀自动机)
[SPOJ]Longest Common Substring(后缀自动机) 题面 Vjudge 题意:求两个串的最长公共子串 题解 \(SA\)的做法很简单 不再赘述 对于一个串构建\(SAM\) 另 ...
- 【SPOJ】Distinct Substrings(后缀自动机)
[SPOJ]Distinct Substrings(后缀自动机) 题面 Vjudge 题意:求一个串的不同子串的数量 题解 对于这个串构建后缀自动机之后 我们知道每个串出现的次数就是\(right/e ...
- 【SPOJ】Distinct Substrings/New Distinct Substrings(后缀数组)
[SPOJ]Distinct Substrings/New Distinct Substrings(后缀数组) 题面 Vjudge1 Vjudge2 题解 要求的是串的不同的子串个数 两道一模一样的题 ...
- 【SPOJ】Power Modulo Inverted(拓展BSGS)
[SPOJ]Power Modulo Inverted(拓展BSGS) 题面 洛谷 求最小的\(y\) 满足 \[k\equiv x^y(mod\ z)\] 题解 拓展\(BSGS\)模板题 #inc ...
- 【SPOJ419】Transposing is Fun Pólya定理+欧拉函数
[SPOJ419]Transposing is Fun 题意:给你一个$2^a\times2^b$的矩阵,将$1...n$中的数依次从左到右,从上往下填到矩阵里,再把矩阵转置,然后把所有数从左到右,从 ...
- 【SPOJ】QTREE7(Link-Cut Tree)
[SPOJ]QTREE7(Link-Cut Tree) 题面 洛谷 Vjudge 题解 和QTREE6的本质是一样的:维护同色联通块 那么,QTREE6同理,对于两种颜色分别维护一棵\(LCT\) 每 ...
随机推荐
- flex布局全解析
前言 很长一段时间, 我知道有flex这个布局方式, 但是始终没有去学它. 3点原因: 感觉还比较新, 担心兼容性不好. 普通的布局方式能满足我的绝大多数需求. 好像蛮复杂的. 最近由于开发需要, 学 ...
- NDK(14)Native的char*和Java的String相互转换
转自: http://www.cnblogs.com/canphp/archive/2012/11/13/2768937.html 首先确保C/C++源文件的字符编码是UTF-8与JAVA的class ...
- ORACLE将表中的数据恢复到某一个时间点
执行如下SQL将test_temp表中的数据恢复到 2013-04-26 21:06:00 注意,这里一定要先删除全部数据,否则可能会导致数据重复 delete from test_temp; in ...
- C++ STL之list容器的基本操作
由于list和vector同属于序列式容器,有很多相同的地方,而上一篇中已经写了vector,所以这一篇着重写list和vector的不同之处和特有之处. 特别注意的地方: (1)STL中迭代器容器中 ...
- Redis VS Memcached
1. Redis & Memecached比较 内存管理 持久化 数据类型 客户端支持 并发性能 Memcached 预分配的内存池的方式 不支持持久化 支持简单的key-value存储 ...
- 1287. Mars Canals(DP)
1287 水DP #include <iostream> #include<cstdio> #include<cstring> #include<algori ...
- bzoj2436
不难发现两边的活动是交替进行的,我们可以dp 先对时间离散化,设f[i,j]到时间i一个会场选j个活动,另一个会场最多有多少活动,那么f[i,j]=max(f[k,j]+s[k,i],f[k,j-s[ ...
- HDU 3467 (求五个圆相交面积) Song of the Siren
还没开始写题解我就已经内牛满面了,从晚饭搞到现在,WA得我都快哭了呢 题意: 在DotA中,你现在1V5,但是你的英雄有一个半径为r的眩晕技能,已知敌方五个英雄的坐标,问能否将该技能投放到一个合适的位 ...
- hdu 2544最短路——最短路的初次总结 UESTC 6th Programming Contest Online
这是一道标准的模板题,所以拿来作为这一段时间学习最短路的总结题目. 题意很简单: 有多组输入数据,每组的第一行为两个整数n, m.表示共有n个节点,m条边. 接下来有m行,每行三个整数a, b, c. ...
- Oracle数据库导出
一. pl/SQL方式 1.打开plsql,找到工具栏,导出表