挺神仙的置换题

SP422 TRANSP2 - Transposing is Even More Fun

这个博客除了开始举例子别的都是对的:

https://blog.csdn.net/BraketBN/article/details/50668414

首先理解题意:

就是单纯的矩阵转置,一行一行存储。

(全部下标从0开始)

一个位置(i,j)在转置后会变成(j,i)

原来存储的位置是(下标从0开始):i*2^b+j

现在是:j*2^a+i

发现其实就是一个二进制数循环右移b位得到的

向要到的位置连边,会形成K个置换环

每个置换环内部换会len-1省一次

总共就是:2^(a+b)-K

关键是求K

问题转化为:

有2^(a+b)个元素

两个元素是等价类当且仅当A循环右移b位和B相等

求等价类的个数

分母枚举所有的置换

分子计算所有不动点的个数

画画图,发现,在(a+b)的环上,一次走b步,最后有gcd(a,b)个置换环,和一次走gcd(a,b)步是一样的

所以,可以这样写,然后反演:

摘自:https://blog.csdn.net/BraketBN/article/details/50668414

然后,2的次幂可以预处理,phi线性筛,d可以快速质因数分解,然后dfs枚举约数

n直接求逆元,复杂度就是O(因子个数*T)

代码:

#include<bits/stdc++.h>
#define reg register int
#define il inline
#define numb (ch^'0')
using namespace std;
typedef long long ll;
il void rd(int &x){
char ch;x=;bool fl=false;
while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
for(x=numb;isdigit(ch=getchar());x=x*+numb);
(fl==true)&&(x=-x);
}
namespace Miracle{
const int mod=;
const int N=1e6+;
int vis[N],pri[N],phi[N],tot;
int mindiv[N];
int yin[],zhi[],cnt;
void sieve(){
phi[]=;
for(reg i=;i<=1e6;++i){
if(!vis[i]){
vis[i]=;
mindiv[i]=i;
pri[++tot]=i;
phi[i]=i-;
}
for(reg j=;j<=tot;++j){
if(pri[j]*i>1e6) break;
vis[pri[j]*i]=;
mindiv[i*pri[j]]=pri[j];
if(i%pri[j]==){
phi[i*pri[j]]=phi[i]*pri[j];
break;
}else{
phi[i*pri[j]]=phi[i]*phi[pri[j]];
}
}
}
}
ll ans;
int pw[N];
int g,n;
void dfs(int x,int fac){
if(x==cnt+){
ans=(ans+(ll)pw[fac*g]*phi[n/fac]%mod)%mod;
return;
}
dfs(x+,fac);
int tmp=yin[x];
for(reg i=;i<=zhi[x];++i){
dfs(x+,fac*tmp);
tmp=tmp*yin[x];
}
}
int gcd(int a,int b){
return b?gcd(b,a%b):a;
}
int qm(int x,int y){
int ret=;
while(y){
if(y&) ret=(ll)ret*x%mod;
x=(ll)x*x%mod;
y>>=;
}
return ret;
}
int main(){
int t,a,b;
sieve();
pw[]=;
for(reg i=;i<=1e6;++i) pw[i]=(ll)pw[i-]*%mod; rd(t);
while(t--){
rd(a);rd(b);
if(a==||b==){
puts("");continue;
}
g=gcd(a,b);
n=(a+b)/gcd(a,b);
// cout<<" n "<<n<<endl;
cnt=;
ans=; int tmp=n;
while(mindiv[tmp]){
yin[++cnt]=mindiv[tmp];
zhi[cnt]=;
while(mindiv[tmp]==yin[cnt]) tmp/=mindiv[tmp],++zhi[cnt];
}
dfs(,); ans=(ll)ans*qm(n,mod-)%mod;
ans=(qm(,a+b)-ans+mod)%mod;
printf("%lld\n",ans);
}
return ;
} }
signed main(){
Miracle::main();
return ;
} /*
Author: *Miracle*
Date: 2019/2/18 11:31:26
*/

总结:
一个置换思想套置换本身的好题

反演还过来凑凑热闹

SP422 TRANSP2 - Transposing is Even More Fun——置换群+反演的更多相关文章

  1. SPOJ 422 Transposing is Even More Fun(polay计数)

    题目链接:http://www.spoj.com/problems/TRANSP2/ 题意: 思路:不妨设a=1,b=2, 我们发现(001,010,100)组成一个置换,(011,110,101)组 ...

  2. poj1026 Cipher ——置换群

    link:http://poj.org/problem?id=1026 其实这道题目和poj2369这道题目一样. 都是基础的置换群题目.把那道题目理解了,这道题就没问题了. 不过我的方法貌似比较挫, ...

  3. poj2369 Permutations ——置换群

    link:http://poj.org/problem?id=2369 置换群,最简单的那种. 找所有数字循环节的最小公倍数. /* ID: zypz4571 LANG: C++ TASK: perm ...

  4. 组合数学 - 置换群的幂运算 --- poj CARDS (洗牌机)

    CARDS Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 1448   Accepted: 773 Description ...

  5. [wikioi 2845]排序的代价(置换群)

    有一列数,要对其进行排序(升序).排序只能通过交换来实现.每次交换,可以选择这列数中的任意二个,交换他们的位置,并且交换的代价为二个数的和.排序的总代价是排序过程中所有交换代价之和.先要求计算,对于任 ...

  6. POJ 3270 Cow Sorting(置换群)

    题目链接 题意 : N头牛,每个牛的坏脾气都有一个值,每个值都不相同,把这个值按照从小到大排序,如果两个值交换,那么会花掉这两个值之和的时间,让你花最少的时间将每个值从小到大排好序,求最小的总时间. ...

  7. POJ 1026 Cipher(置换群)

    题目链接 题意 :由n个数字组成的密钥,每个数字都不相同,都在1-n之间,有一份长度小于等于n的信息,要求将信息放到密钥下边,一一对应,信息不足n的时候补空格,然后将位置重新排列,将此过程重复k次,求 ...

  8. poj 1026(置换群)

    题意:给你一个变换规则,和一个字符串,问经过k次变换后得到的字符串. 思路:开始的时候试图去找它的整个周期,谁知道周期太大了,各种RE,后来在得知此题需要用置换群来优化,第一次接触置换群学习了下! 代 ...

  9. 【SPOJ】Transposing is even more fun!

    题意: 给出a.b 表示按先行后列的方式储存矩阵 现在要将其转置 可以交换两个点的位置 求最小操作次数 题解: 储存可以将其视为拉成一条链 设a=5.b=2 则在链上坐标用2^***(a,b)表示为( ...

随机推荐

  1. 《基于Cortex-M4的ucOS-III的应用》课程设计 结题报告

    <基于Cortex-M4的ucOS-III的应用>课程设计 结题报告 小组成员姓名:20155211 解雪莹 20155217 杨笛 20155227 辜彦霖 指导教师:娄嘉鹏 一.设计方 ...

  2. # 2017-2018-2 20155319 『网络对抗技术』Exp8:Web基础

    2017-2018-2 20155319 『网络对抗技术』Exp8:Web基础 一.原理与实践说明 1.实践具体要求 (1).Web前端HTML(0.5分) 能正常安装.启停Apache.理解HTML ...

  3. 【第八课】php-fpm.conf配置文件解析

    在discuz论坛的nginx配置文件当中,我们可以看到有一段php解析的配置,如下: location ~ \.php$ { try_files $uri = 404; fastcgi_pass 1 ...

  4. linux 定时器原理

    内核定时器:    unsigned long timeout = jiffies + (x * HZ);    while(1) {        // Check the condition.   ...

  5. 利用Junit实现eclipse单元测试

    在eclipse中使用Junit进行单元测试 今天学会了用Junit在eclipse中进行单元测试,代码的测试工作,在整个软件开发中占有总要的地位,无论是代码开发阶段,还是代码维护阶段.另外边开发边测 ...

  6. coinmarketcap前20之cardano卡尔达诺(ADA艾达币)

    1. 在开始讲述cardano前,我先说说自己在coinmarketcap前20系列的"学习方法". 最初,我把前20做了一个简单表格,不做任何功课的基础上,记录自己对它们的简要认 ...

  7. 小学四则运算APP 第一个冲刺阶段 第三天

    团队成员:陈淑筠.杨家安.陈曦 团队选题:小学四则运算APP 第一次冲刺阶段时间:11.17~11.27 本次发布是在与团队成员解决了昨天问题的基础上,再增加了几个界面,增加了一些功能,修改与增加的代 ...

  8. Github作为图床的一个小坑

    Github作为图床的一个小坑 前言 听了少铭同学建议把github作为图床,结果遇到了一个小坑,总是显示不出来图片. 问题描述与解决 形如下的链接是显示不出来的: https://github.co ...

  9. Java 笔记——在 IDEA 中使用 Maven 配置和使用 MyBatis

    1.前言 MyBatis 是什么? MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射. MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集. ...

  10. PGSQL 数据库备份练习

    截图先 慢慢说 1. 简单使用方法 先用 之前的setx 命令设置环境变量. set path=%PATH% ---其实第一步没必要..... 跟人学的 setx PATH "%path%& ...