洛谷 - Sdchr 的邀请赛 T4 信息传递
(乱搞艹爆正解系列)
对不起,由于博主太弱了,并不会正解的多项式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 信息传递的更多相关文章
- 洛谷 - Sdchr 的邀请赛 T1 取石子
比赛的时候都推出来了和 质因子的指数和有关,硬是没做出来QWQ,我傻死算了 但其实这是一个结论题,因为这本来就是阶梯NIM游戏的模型.阶梯NIM游戏是指,有 n+1 阶台阶(0 ~ n),每阶上都有若 ...
- 洛谷大宁的邀请赛~元旦祭F: U17264 photo(线段树)
标程的写法稍微有点麻烦,其实不需要平衡树也是可以做的. 线段树上维护从左端点开始最远的有拍照的长度,以及区间的最大值. 考虑两段区间合并的时候,显然左区间必须取,右区间的第一个比左区间最大值大的数开始 ...
- 洛谷 1062 NOIP2006普及T4 数列
[题解] 鲜活的水题..我们把数列换成k进制的,发现数列是001,010,011,100,101,110,111...,而第m项用k进制表示的01串刚好就是m的二进制的01串.于是我们预处理k的幂,把 ...
- [洛谷P3982]龙盘雪峰信息解析器
题目大意:给你一串代码,要求进行解码.解码规则详见题目. 解题思路:这是一道字符串处理的题目. 首先,有这么几种情况输出Error: 1.代码中出现除了0和1外的字符. 2.代码长度不是8的倍数. 3 ...
- 洛谷P2661 信息传递(最小环,并查集)
洛谷P2661 信息传递 最小环求解采用并查集求最小环. 只适用于本题的情况.对于新加可以使得两个子树合并的边,总有其中一点为其中一棵子树的根. 复杂度 \(O(n)\) . #include< ...
- tg2015 信息传递 (洛谷p2661)
题目描述 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知道自己的生日.之后每一 ...
- [NOIP2015] 提高组 洛谷P2661 信息传递
题目描述 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知道自己的生日.之后每一 ...
- 洛谷 P2661 信息传递 Label:并查集||强联通分量
题目描述 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知道自己的生日.之后每一 ...
- AC日记——信息传递 洛谷 P2661 (tarjan求环)
题目描述 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知道自己的生日.之后每一 ...
随机推荐
- bzoj2827: 千山鸟飞绝 平衡树 替罪羊树 蜜汁标记
这道题首先可以看出坐标没有什么意义离散掉就好了. 然后你就会发现你要每次都更改坐标,而一旦更改受影响的是坐标里的所有数,要是一个一个的改,会不可描述. 所以换个视角,我们要找的是某只鸟所到每个坐标时遇 ...
- 线程 packaged_task future
http://www.cnblogs.com/haippy/p/3279565.html #include <iostream> // std::cout #include <fut ...
- word公式编辑中的转义字符
Some of the commonly used symbols: \infty - Infinity \leq - Less then or equal \geq - ...
- HDU 多校对抗 F Naive Operations
Naive Operations Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 502768/502768 K (Java/Other ...
- 对比append插入数据产生的redo量
--版本信息 SELECT * FROM v$version; Oracle - Prod PL - Production CORE Production TNS - Production NLSRT ...
- Java拷贝构造函数初尝试
浅复制(浅克隆) :被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象. 深复制(深克隆) :被复制 ...
- Round 0: Regionals 2010 :: NEERC Eastern Subregional
Round 0: Regionals 2010 :: NEERC Eastern Subregional 贴吧题解(官方)? 网上的题解 水 A Murphy's Law 题意:Anka拿着一块涂着黄 ...
- [BZOJ1602&BZOJ1787&BZOJ2144]树上LCA的算法巩固练习
简述求LCA的倍增算法 对于树上的所有节点,我们可以很轻松地通过dfs求出其直接的父亲节点以及其深度 通过类似RMQ的原理我们可以处理出每个节点的第2^i个父亲 //这个过程既可以在dfs之后双重循环 ...
- python基础===pip安装模块失败
此情况只用于网络不畅的安装模块背景: 总出现红色的 Could not find a version that satisfies the requirement pymongo(from versi ...
- js 各种取整方式及方法
1.直接丢弃小数部分,保留整数部分 a:parseInt(1.5555) b: 0|1.5555 2.向上取整 a: Math.ceil(1.5555) b: (1.5555+0.5).toFixed ...