后记:

 
后记:

差不多一个礼拜的时间,把《COM技术内幕》看了一遍,记得08年也这么干过的,可当时没有做笔记,所以这次看的时候,好多都没有印象了,感觉像第一次看一样。还真是好记性不如烂笔头,何况我还不是好记性。所以这次看就做了一下前面的笔记,前面6章的笔记有转载网友的内容,可不知道原创在哪了,在这里对原创者表示感谢。虽然书是看完了,可还谈不上完全理解,项目中也没有用过COM,自己也不知道学了哪天会不会用上。只是觉得工作不忙时,空闲的时间学点东西比浪费掉好。源码都做成了VC的工程文件,前面12章的代码也都在自己机器上验证OK了的,也囫囵吞枣的把代码过了一遍。源码位置http://download.youkuaiyun.com/detail/jjunjoe/3653535

# T446004 不知道 ## 题目背景 不知道,令人闻风丧胆的猫猫魔,福尔魔斯的宿敌。 某一天,她在网上看到了一道小学奥数问题:约瑟夫问题。 ## 题目描述 不知道又要作案了。她让 $n$ 只猫猫站成一行,从左到右初始编号为 $1,2,\dots,n$。同时,它们初始站在与自己编号相同的格子上。 不知道有 $k+1$ 个喜欢的数字 $t_0,t_1,\dots,t_k$ 。它们满足: - $t_0=1$ - 对于 $1\le i\le k$ , $t_{i-1}<t_i$ - $t_k\le n$ 不知道会摸 $n-1$ 轮猫猫,每一轮她都会摸正好一只猫猫。一次摸猫猫遵循以下规则: 1. 从 $0$ 到 $k$ 中随机选择一个数 $i$ 。 1. 若有猫猫现在待在第 $t_i$ 格上,不知道会摸摸这个猫猫,随后这个猫猫将会跑出格子,不再参与后续的任何流程,然后进行第三步;否则回到第一步。 1. 让所有猫猫跑到新的格子上。若此时有 $p$ 只猫猫,它们会在保证相对顺序不变的情况下排到 $[1,p]$ 的格子上。 但是虽然猫猫很可爱,猫猫和不知道都是会厌烦的,所以当只剩一只猫猫时,不知道会停止摸猫猫。请求出每只猫猫最终没被摸的概率。 最终答案对 $998244353$ 取模。 ## 输入格式 第一行两个整数 $n$ 和 $k$ ,代表总共有 $n$ 个猫猫,不知道共有 $k+1$ 个喜欢的数字。 第二行 $k$ 个整数,分别代表 $t_1$ 至 $t_k$ 共 $k$ 个数,中间用空格隔开。 ## 输出格式 一行 $n$ 个整数,第 $i$ 个数表示初始编号为 $i$ 的猫猫没被摸的概率,空格隔开;对 $998244353$ 取模。 ## 输入输出样例 #1 ### 输入 #1 ``` 2 0 ``` ### 输出 #1 ``` 0 1 ``` ## 输入输出样例 #2 ### 输入 #2 ``` 4 1 3 ``` ### 输出 #2 ``` 0 748683265 748683265 499122177 ``` ## 输入输出样例 #3 ### 输入 #3 ``` 8 3 3 6 8 ``` ### 输出 #3 ``` 0 291154603 291154603 582309206 166374059 166374059 748683265 748683265 ``` ## 说明/提示 #### 样例解释: 在第一组样例中,不知道只喜欢 $1$ 这个数字,因此她每次一定会摸当前的第一只猫猫,那么第一只猫猫一定会被摸,第二只猫猫一定不会被摸。 第二组样例中,四只猫猫从左到右不被摸的概率分别为 $0,\frac{1}{4},\frac{1}{4},\frac{1}{2}$ 。 #### 数据范围: **本题采用捆绑测试。** 对所有数据,保证 $1\le n,k\le10^6$ ; $t_i$ 范围见上。 | # | 特殊性质 | 分值 | | :--: | :-------------------: | :--: | | 0 | $n\le 8$ | 10 | | 1 | $k=0$ | 5 | | 2 | $k=1$ | 10 | | 3 | $n\le5\times10^3$ | 15 | | 4 | $k\le 10$ | 15 | | 5 | $n\le2\times10^5$ | 20 | | 6 | 无特殊限制 | 25 | 后记: 花生:话说不知道本名叫什么 福尔魔斯:不知道,所以叫不知道 这道题的c++代码!
03-17
这个问题涉及经典的约瑟夫环问题变种,需要结合概率计算和组合数学的知识。以下是解决该问题的一种高效C++实现思路: ### 主要步骤解析 1. **核心思想**: - 每次从`t[i]`集合中随机选取一个位置尝试淘汰猫猫。 - 如果当前位置存在猫猫,则将其移除,并更新剩余猫猫的位置索引。 - 最终目标是求每个猫猫未被淘汰的概率。 2. **优化方向**: - 直接暴力模拟显然不可行 (`O(n^2)` 时间复杂度),需借助前缀和或动态规划等技巧将时间复杂度降低到线性级别。 - 使用累积乘法逆元预处理加速幂运算部分(对大质数取模时非常有效)。 下面是基于上述分析的一个完整参考代码框架: ```cpp #include <bits/stdc++.h> using namespace std; typedef long long LL; const int MOD = 998244353; // 快速幂模板 LL qpow(LL a, LL b){ LL res = 1; while(b){ if(b & 1) res = (res * a)%MOD; a = (a*a)%MOD; b >>=1; } return res; } int main(){ ios::sync_with_stdio(false); cin.tie(0); int n, k; cin >> n >> k; vector<int> t(k+1); for(int i=1;i<=k;++i) cin>>t[i]; t[k+1]=n+1; // 添加哨兵方便分段处理 vector<LL> inv(n + 1), pre_inv_sum(n + 1, 0); inv[1]=1; for(int i=2;i<=n;i++) { inv[i]=(MOD-MOD/i)*inv[MOD%i]%MOD; } // 预处理前缀逆元之和 for(int i=1;i<=n;i++) { pre_inv_sum[i] = (pre_inv_sum[i-1]+inv[i])%MOD; } vector<LL> p(n+1,0); // 存储每个猫存活的概率 p[n]=qpow((LL)(k+1),MOD-2); // 初始化最后一个猫的概率 // 动态规划递推 for(int r=n;r>=1;r--){ LL prob_r=p[r]; // 当前轮选r的概率 // 更新左侧猫的贡献 for(auto ti:t){ if(ti <=r &&ti >0 ){ int l=max(t[(lower_bound(t.begin(),t.end(),ti)-t.begin()-1],1); // 找左边最近的关键点 LL add=((prob_r*(pre_inv_sum[r-l]-pre_inv_sum[ti-l-1]))%MOD+MOD)%MOD; // 将这部分加权平均分配给l..ti-1区间的猫 for(int j=l;j<ti;j++) p[j]=(p[j]+add*inv[ti-j]%MOD)%MOD; } } // 自己这一项清零,因为已经被淘汰 p[r]=0; } // 输出结果 for(int i=1;i<n;i++) cout<<p[i]<<" "; cout<<p[n]<<'\n'; } ``` --- 此算法的核心在于利用快速幂、累加逆元等方式减少不必要的重复计算量,从而达到最优性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值