(乱搞艹爆正解系列)

对不起,由于博主太弱了,并不会正解的多项式exp(甚至多项式exp我都不会2333)。

只能来说一说我是怎么乱搞的啦QWQ

首先这个题最关键的性质是: 一个在原置换 g 中长度为 l 的环,在 f 中会被拆成 gcd(l,n) 个 长度为 l/gcd(l,n) 的环  [可以类比同余系中的一些变换]

所以知道了这个,我们怎么反着搞回去呢???

先 O(N) 找出所有循环的长度,然后记 num[i] 为 f 中长度为i的环有多少个。这个时候,我们再知道了 哪些长度一样的环被合并到了一起,就可以计算出答案了。

因为长度不一样的环之间互不影响,所以我们可以把每个长度的环的答案乘起来,就是最终答案了(如果f中没有长度为i的环,那么这个长度的环的答案是1)。

于是我们就可以先从1到n扫一遍,把每个 i 存到 i/gcd(i,n) 的 vector 中去,表示 gcd(i,n) 个 i/gcd(i,n) 可以合并成一个 长度为i的环。

然后对于每个长度,我们只需要扫它的倍数dp即可,复杂度O(玄学)。

(至于中间怎么推dp的式子就不说了,就是一些组合数学的基本功练习2333)

为什么是 O(玄学)呢?

单纯的扫一遍倍数已经是 O(N * log (N))了,但是因为很多地方可以不用扫(比如没出现的环长,或者一种环长的环的长度和很小,不需要用到很大的dp数组),仔细算一下,扫的过程其实是 O(图中环的个数) 的,已经是低于线性的了。

但是可能一个vector里面会有很多元素啊,这样dp的时候会不会炸啊???

就比如 i=1 的时候,我们可能要扫 1~n中所有数的dp数组,再乘一个 vector 的大小,难道不是秒变 O(N^2)了吗?

但可以发现此时vector中的元素只有 n 的约数(请自行yy为什么),1e5以下的约数最多的到100吗(不太清楚)??

所以就算用心卡我,也很难卡掉吧QWQ

(达成目标 : 在代码量是标程 1/3的情况下 速度 比标程快了8倍  2333)

#include<bits/stdc++.h>
#define ll long long
using namespace std;
#define pb push_back
const int maxn=100005,ha=998244353;
inline int add(int x,int y){ x+=y; return x>=ha?x-ha:x;}
inline void ADD(int &x,int y){ x+=y; if(x>=ha) x-=ha;}
inline int ksm(int x,int y){
int an=1;
for(;y;y>>=1,x=x*(ll)x%ha) if(y&1) an=an*(ll)x%ha;
return an;
} vector<int> g[maxn],w[maxn];
int n,a[maxn],num[maxn],ans=1;
int jc[maxn],ni[maxn],f[maxn];
bool v[maxn]; int gcd(int x,int y){ return y?gcd(y,x%y):x;} inline int P(int x,int y){ return jc[x]*(ll)ni[x-y]%ha;} inline int work(int x){
int an=0;
while(!v[x]) an++,v[x]=1,x=a[x];
return an;
} inline void solve(){
jc[0]=1;
for(int i=1;i<=n;i++) jc[i]=jc[i-1]*(ll)i%ha;
ni[n]=ksm(jc[n],ha-2);
for(int i=n;i;i--) ni[i-1]=ni[i]*(ll)i%ha; for(int i=1;i<=n;i++) if(!v[i]) num[work(i)]++; for(int i=n;i;i--) g[i/gcd(i,n)].pb(i); for(int i=1;i<=n;i++)
for(int j=0;j<g[i].size();j++) w[i].pb(ksm(i,g[i][j]/i-1)); for(int i=1;i<=n;i++) if(num[i]){
int T=num[i]*i,now;
f[0]=1; for(int j=i;j<=T;j+=i){
f[j]=0;
for(int l=g[i].size()-1;l>=0;l--){
now=g[i][l];
if(now>j) break; ADD(f[j],f[j-now]*(ll)P(j/i-1,now/i-1)%ha*(ll)w[i][l]%ha);
}
} ans=ans*(ll)f[T]%ha;
// cout<<f[T]<<endl;
}
} int main(){
// freopen("data.in","r",stdin);
// freopen("data.out","w",stdout); scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",a+i); solve(); printf("%d\n",ans);
return 0;
}

  

洛谷 - Sdchr 的邀请赛 T4 信息传递的更多相关文章

  1. 洛谷 - Sdchr 的邀请赛 T1 取石子

    比赛的时候都推出来了和 质因子的指数和有关,硬是没做出来QWQ,我傻死算了 但其实这是一个结论题,因为这本来就是阶梯NIM游戏的模型.阶梯NIM游戏是指,有 n+1 阶台阶(0 ~ n),每阶上都有若 ...

  2. 洛谷大宁的邀请赛~元旦祭F: U17264 photo(线段树)

    标程的写法稍微有点麻烦,其实不需要平衡树也是可以做的. 线段树上维护从左端点开始最远的有拍照的长度,以及区间的最大值. 考虑两段区间合并的时候,显然左区间必须取,右区间的第一个比左区间最大值大的数开始 ...

  3. 洛谷 1062 NOIP2006普及T4 数列

    [题解] 鲜活的水题..我们把数列换成k进制的,发现数列是001,010,011,100,101,110,111...,而第m项用k进制表示的01串刚好就是m的二进制的01串.于是我们预处理k的幂,把 ...

  4. [洛谷P3982]龙盘雪峰信息解析器

    题目大意:给你一串代码,要求进行解码.解码规则详见题目. 解题思路:这是一道字符串处理的题目. 首先,有这么几种情况输出Error: 1.代码中出现除了0和1外的字符. 2.代码长度不是8的倍数. 3 ...

  5. 洛谷P2661 信息传递(最小环,并查集)

    洛谷P2661 信息传递 最小环求解采用并查集求最小环. 只适用于本题的情况.对于新加可以使得两个子树合并的边,总有其中一点为其中一棵子树的根. 复杂度 \(O(n)\) . #include< ...

  6. tg2015 信息传递 (洛谷p2661)

    题目描述 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知道自己的生日.之后每一 ...

  7. [NOIP2015] 提高组 洛谷P2661 信息传递

    题目描述 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知道自己的生日.之后每一 ...

  8. 洛谷 P2661 信息传递 Label:并查集||强联通分量

    题目描述 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知道自己的生日.之后每一 ...

  9. AC日记——信息传递 洛谷 P2661 (tarjan求环)

    题目描述 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知道自己的生日.之后每一 ...

随机推荐

  1. [bzoj 1208]STL水过

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1208 看网上的题解都用的手写数据结构……然而直接用set的lower_bound就水过去了 ...

  2. Codeforces Global Round 1 (A-E题解)

    Codeforces Global Round 1 题目链接:https://codeforces.com/contest/1110 A. Parity 题意: 给出{ak},b,k,判断a1*b^( ...

  3. c++虚析构函数的必要性

    我们知道,用C++开发的时候,用来做基类的类的析构函数一般都是虚函数. 可是,为什么要这样做呢?下面用一个小例子来说明: #include<iostream> using namespac ...

  4. 栈与递归的实现(Hanoi塔问题等等)

    函数中有直接或间接地调用自身函数的语句,这样的函数称为递归函数.递归函数用 得好,可简化编程工作.但函数自己调用自己,有可能造成死循环.为了避免死循环,要 做到两点: (1) 降阶.递归函数虽然调用自 ...

  5. 【BZOJ】1592: [Usaco2008 Feb]Making the Grade 路面修整

    [算法]动态规划DP [题解] 题目要求不严格递增或不严格递减. 首先修改后的数字一定是原来出现过的数字,这样就可以离散化. f[i][j]表示前i个,第i个修改为第j个数字的最小代价,a表示排序后数 ...

  6. UVa 12265 贩卖土地 单调栈

    题意 输入一个\(n\times m\)的矩阵,每个格子可能是空地,也可能是沼泽.对于每个空地格子,求出以它为右下角的空矩形的最大周长,然后统计每个周长出现了多少次. 思路 对于 每一行 每两个沼泽之 ...

  7. MSP432P401R时钟入门

    拿到msp432的板子差不多一年了,刚刚进行了开机点亮LED工程:         首先是msp432的时钟模块(CS),个人理解msp432最特色的功能应该是超低功耗和高性能的组合.432系列的时钟 ...

  8. kuangbin带你飞 生成树专题 : 次小生成树; 最小树形图;生成树计数

    第一个部分 前4题 次小生成树 算法:首先如果生成了最小生成树,那么这些树上的所有的边都进行标记.标记为树边. 接下来进行枚举,枚举任意一条不在MST上的边,如果加入这条边,那么肯定会在这棵树上形成一 ...

  9. 【Uva11762】Race to 1

    模拟马尔可夫过程,具体看书. #include<bits/stdc++.h> #define N 1000010 using namespace std; ; void calcprime ...

  10. scrapy模拟知乎登录(无验证码机制)

    ---恢复内容开始--- spiders 文件夹下新建zhihu.py文件(从dos窗口中进入虚拟环境,再进入工程目录之后输入命令 scrapy genspider zhihu www.zhihu.c ...