题意:

给出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!的更多相关文章

  1. 【SPOJ】NUMOFPAL - Number of Palindromes(Manacher,回文树)

    [SPOJ]NUMOFPAL - Number of Palindromes(Manacher,回文树) 题面 洛谷 求一个串中包含几个回文串 题解 Manacher傻逼题 只是用回文树写写而已.. ...

  2. 【SPOJ】Substrings(后缀自动机)

    [SPOJ]Substrings(后缀自动机) 题面 Vjudge 题意:给定一个长度为\(len\)的串,求出长度为1~len的子串中,出现最多的出现了多少次 题解 出现次数很好处理,就是\(rig ...

  3. 【SPOJ】Longest Common Substring II (后缀自动机)

    [SPOJ]Longest Common Substring II (后缀自动机) 题面 Vjudge 题意:求若干个串的最长公共子串 题解 对于某一个串构建\(SAM\) 每个串依次进行匹配 同时记 ...

  4. 【SPOJ】Longest Common Substring(后缀自动机)

    [SPOJ]Longest Common Substring(后缀自动机) 题面 Vjudge 题意:求两个串的最长公共子串 题解 \(SA\)的做法很简单 不再赘述 对于一个串构建\(SAM\) 另 ...

  5. 【SPOJ】Distinct Substrings(后缀自动机)

    [SPOJ]Distinct Substrings(后缀自动机) 题面 Vjudge 题意:求一个串的不同子串的数量 题解 对于这个串构建后缀自动机之后 我们知道每个串出现的次数就是\(right/e ...

  6. 【SPOJ】Distinct Substrings/New Distinct Substrings(后缀数组)

    [SPOJ]Distinct Substrings/New Distinct Substrings(后缀数组) 题面 Vjudge1 Vjudge2 题解 要求的是串的不同的子串个数 两道一模一样的题 ...

  7. 【SPOJ】Power Modulo Inverted(拓展BSGS)

    [SPOJ]Power Modulo Inverted(拓展BSGS) 题面 洛谷 求最小的\(y\) 满足 \[k\equiv x^y(mod\ z)\] 题解 拓展\(BSGS\)模板题 #inc ...

  8. 【SPOJ419】Transposing is Fun Pólya定理+欧拉函数

    [SPOJ419]Transposing is Fun 题意:给你一个$2^a\times2^b$的矩阵,将$1...n$中的数依次从左到右,从上往下填到矩阵里,再把矩阵转置,然后把所有数从左到右,从 ...

  9. 【SPOJ】QTREE7(Link-Cut Tree)

    [SPOJ]QTREE7(Link-Cut Tree) 题面 洛谷 Vjudge 题解 和QTREE6的本质是一样的:维护同色联通块 那么,QTREE6同理,对于两种颜色分别维护一棵\(LCT\) 每 ...

随机推荐

  1. C++:常类型Const

    常类型:使用类型修饰符const说明的类型,常类型的变量或对象成员的值在程序运行期间是不可改变的. 3.10.1 常引用 如果在说明引用时用const修饰,则被说明的引用为常引用.如果用常引用做形参, ...

  2. PCL—低层次视觉—点云分割(最小割算法)

    1.点云分割的精度 在之前的两个章节里介绍了基于采样一致的点云分割和基于临近搜索的点云分割算法.基于采样一致的点云分割算法显然是意识流的,它只能割出大概的点云(可能是杯子的一部分,但杯把儿肯定没分割出 ...

  3. redis twitter

    http://redis.io/topics/twitter-clone 翻译:http://my.oschina.net/Twitter/blog/287539

  4. Classpath entry org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER will not be exported

    打开navigator,修改下面的classpath文件: 将<classpathentry kind="con" path="org.maven.ide.ecli ...

  5. NDK(16)Jni中GetStaticFieldID和GetMethodID 中的类型标识串

    env在GetStaticFieldID和GetMethodID 时,函数参数和返回值的类型要指定类型标识串,如: jmethodID init = env->GetMethodID(clz,& ...

  6. Java开发之单例设计模式

    设计模式之单例模式: 一.单例模式实现特点:①单例类在整个应用程序中只能有一个实例(通过私有无参构造器实现):②单例类必须自己创建这个实例并且可供其他对象访问(通过静态公开的访问权限修饰的getIns ...

  7. Redis安装教程

    1. Linux下Redis安装教程 (1)安装 #tar xf redis-2.6.14.tar.gz #cd redis-2.6.14 #make #make install (2)配置 修改re ...

  8. HDU 1710 Binary Tree Traversals

    题意:给出一颗二叉树的前序遍历和中序遍历,输出其后续遍历 首先知道中序遍历是左子树根右子树递归遍历的,所以只要找到根节点,就能够拆分出左右子树 前序遍历是按照根左子树右子树递归遍历的,那么可以找出这颗 ...

  9. 如何在Asp.Net WebApi接口中,验证请求参数中是否携带token标识!

    [BasicAuthentication] public abstract class ApiControllerBase : ApiController { #region Gloal Proper ...

  10. 监听某个div或其它标签的大小改变来执行相应的处理

    jquery 默认的resize只能监听到浏览器窗口大小的改变,但我们在实际使用过程中有可能还需要监听某个div或其它标签的大小改变来执行相应的处理,如果使用默认的resize就无能为力了.怎么办呢, ...