题目

对于一个01串,定义\(f(s)\)为\(f(s) = \sum_{i=0}^{\lfloor \frac{|s|}{2} \rfloor -1 }[s_i=s_{|s|-1-i}]\)

定义\(S\)所有子串集合为\(P(S)\) ,求\(\sum_{s \in P(S)} f(s)\)

\(|S| \le 250000\)

题解

  • 这题我看看到数据范围感到莫名奇怪却不知道奇怪在哪里?

  • 60 pts

  • 设\(f_{i}\)表示\(i\)位置开头的子序列的贡献,考虑增量

  • 每次增量一个$ s_n $即对所有的 $ i \lt n $ 执行 $ f_i = \sum_{j=i}^{n-1} f_j + 2^{n-i-1}[s_i==s_j] $

  • 相当于把所有位置做后缀和再在和$ s_n $相同的位置加上一个什么东西。。。

  • 后缀和好像没法优化,那似乎如果我们直接出一个维护每次后缀和再考虑这种奇怪的加一个东西,

    就可以转化成下面的100分做法来做了,可能装饰一下会是个不错的题?

  • 100 pts

  • \[\begin{align}
    ans &= \sum_{i=0}^{n-1}\sum_{j\gt i}^{n-1} [s_i=s_j]2^{j-i-1}\sum_{k=0}^{min(i-1,n-1-j)}(^{i-1}_{k})(^{n-1-j}_k)\\
    由于&\sum_{k=0} (^i_k)(^j_k) = \sum_{k=0} (^i_k)(^j_{j-k}) = (^{i+j}_j) \\
    ans &= \sum_{i=0}^{n-1}\sum_{j\gt i}^{n-1} [s_i=s_j]2^{j-i-1}(^{n+i-j-2}_{i-1}) \\
    &考虑01串并记reverse(s)=t,组合数拆开m,做两遍下面的东西\\
    &= \sum_{k=0}^{n-2} 2^k(n-2-k)! \sum_{i=0}^{n-2-k} \frac{s_i}{i!} \times \frac{t_{n-2-k-i}}{(n-2-k-i)!} \\
    &直接卷就可以了\\
    \end{align}
    \]

    • 之后我知道哪里奇怪了,FFT的话大致要四倍的数组,而2.5e5*4=1e6,十分惊人的暗示!
    1. #include<bits/stdc++.h>
    2. #define mod 998244353
    3. using namespace std;
    4. const int N=1000010,G=3;
    5. int n,a[N],b[N],c[N],ny[N],fac[N],inv[N],L,len,rev[N],pw2[N],iv;
    6. char s[N];
    7. void inc(int&x,int y){x+=y;if(x>=mod)x-=mod;}
    8. int pw(int x,int y){
    9. int re=1;if(y<0)y+=mod-1;
    10. while(y){
    11. if(y&1)re=1ll*re*x%mod;
    12. y>>=1;x=1ll*x*x%mod;
    13. }return re;
    14. }
    15. void ntt(int*A,int f){
    16. for(int i=0;i<len;++i)if(i<rev[i])swap(A[i],A[rev[i]]);
    17. for(int i=1;i<len;i<<=1){
    18. int wn=pw(G,f*(mod-1)/2/i);
    19. for(int j=0;j<len;j+=(i<<1)){
    20. int w=1;
    21. for(int k=0;k<i;++k,w=1ll*w*wn%mod){
    22. int x=A[j+k],y=1ll*w*A[j+k+i]%mod;
    23. A[j+k]=(x+y)%mod;A[j+k+i]=(x-y+mod)%mod;
    24. }
    25. }
    26. }
    27. if(!~f)for(int i=0;i<len;++i)A[i]=1ll*iv*A[i]%mod;
    28. }
    29. void calc(){
    30. ntt(a,1);ntt(b,1);
    31. for(int i=0;i<len;++i)a[i]=1ll*a[i]*b[i]%mod;
    32. ntt(a,-1);
    33. for(int i=0;i<len;++i){inc(c[i],a[i]);a[i]=b[i]=0;}
    34. }
    35. int main(){
    36. freopen("count.in","r",stdin);
    37. freopen("count.out","w",stdout);
    38. scanf("%s",s);n=strlen(s);
    39. ny[1]=pw2[0]=1;
    40. for(int i=pw2[1]=2;i<=n;++i){
    41. ny[i]=1ll*(mod-mod/i)*ny[mod%i]%mod;
    42. pw2[i]=(pw2[i-1]<<1)%mod;
    43. }
    44. for(int i=fac[0]=inv[0]=1;i<=n;++i){
    45. fac[i]=1ll*fac[i-1]*i%mod;
    46. inv[i]=1ll*inv[i-1]*ny[i]%mod;
    47. }
    48. for(int i=0;i<n;++i){
    49. a[i]=s[i]=='1'?inv[i]:0;
    50. b[i]=s[n-1-i]=='1'?inv[i]:0;
    51. }
    52. for(len=1;len<(n<<1);len<<=1,++L);
    53. for(int i=0;i<len;++i)rev[i]=(rev[i>>1]>>1)|((i&1)<<(L-1));
    54. iv=pw(len,mod-2);
    55. calc();
    56. for(int i=0;i<n;++i){
    57. a[i]=s[i]=='0'?inv[i]:0;
    58. b[i]=s[n-1-i]=='0'?inv[i]:0;
    59. }
    60. calc();
    61. int ans=0;
    62. for(int i=0;i<=n-2;++i)inc(ans,1ll*pw2[i]*fac[n-2-i]%mod*c[n-2-i]%mod);
    63. cout<<ans<<endl;
    64. return 0;
    65. }

【JZOJ6225】【20190618】计数的更多相关文章

  1. 计数排序(counting-sort)——算法导论(9)

    1. 比较排序算法的下界 (1) 比较排序     到目前为止,我们已经介绍了几种能在O(nlgn)时间内排序n个数的算法:归并排序和堆排序达到了最坏情况下的上界:快速排序在平均情况下达到该上界.   ...

  2. Objective-C内存管理之引用计数

    初学者在学习Objective-c的时候,很容易在内存管理这一部分陷入混乱状态,很大一部分原因是没有弄清楚引用计数的原理,搞不明白对象的引用数量,这样就当然无法彻底释放对象的内存了,苹果官方文档在内存 ...

  3. 最小生成树计数 bzoj 1016

    最小生成树计数 (1s 128M) award [问题描述] 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一 ...

  4. swift学习笔记5——其它部分(自动引用计数、错误处理、泛型...)

    之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...

  5. [LeetCode] Count and Say 计数和读法

    The count-and-say sequence is the sequence of integers beginning as follows:1, 11, 21, 1211, 111221, ...

  6. C++ 引用计数技术及智能指针的简单实现

    一直以来都对智能指针一知半解,看C++Primer中也讲的不够清晰明白(大概是我功力不够吧).最近花了点时间认真看了智能指针,特地来写这篇文章. 1.智能指针是什么 简单来说,智能指针是一个类,它对普 ...

  7. css-列表或标题的多级计数

    利用css实现多级计数,比如1/1.1/1.1.1这种层层嵌套的计数,主要利用到counter-reset/counter-increment/counter/content/:before. 一.标 ...

  8. csv 中 数值被自动转换成科学计数法 的问题 excel打开后数字用科学计数法显示且低位变0的解决方法

    保存在csv中的 013812345678,前面的0会被去掉,后面是科学计数法显示.保存成 col1,="013812345678" 即可. 注意,分隔符逗号后面直接接“=”等号. ...

  9. 用uniq来处理文件重复数据--交集,差集,计数等(转)

    经常有这样的需求:两个文本文件要求取重复的行或只取不重复的,简单的情况下用sort和uniq来处理是非常方便的: 利用现存两个文件,生成一个新的文件 取出两个文件的并集(重复的行只保留一份) 取出两个 ...

随机推荐

  1. linux上文件的上传和下载

    现整理一篇linux上文件的上传和下载 第一种方式就是在windos上安装工具 如: 工具如何使用我就不赘述了,easy 第二种方式就是使用liux的命令(首先是文件上传) 上传文件(首先创建文件夹如 ...

  2. easy ui 弹框叠加问题

    1.框架用的是.net MVC,Index页面如下所示: @{ Layout = "~/Views/Shared/_CustomerLayout.cshtml"; ViewBag. ...

  3. [Props] vue组件间的传值及校验

    基本用法 Prop的基本用法很简单,只需要在子组件的Vue实例中定义该属性并把值设为目标属性的数组即可 Vue.component('child', { ... // 接收message props: ...

  4. linux上SVN出现 "Unable to connect to a repository at URL 'svn://xx.xx.xx.xx/xxx' 和 No repository ...

    centos上安装了svn, 有时候会不知道什么原因出现客户端小乌龟无法连接或无法提交等情况. 1. 万能重启,xshell连接服务器,输入 service svnserve restart 命令. ...

  5. 关闭firefox火狐浏览器下载完成时自动扫描(49.0.2以后版本)

    本人自己找到的方法,亲测有效,如下:1.在火狐浏览器地址里输入about:config回车,可能会提示“这可能使质量保证失效”,点击[我了解此风险!]2.在搜索框里输入browser.safebrow ...

  6. Windows安装redis报错处理(转!)

    要谈则谈,要打便打! ---2019.5.9,贸易战 转自:http://www.yayihouse.com/yayishuwu/chapter/1297 安装redis报错信息 [9204] 15 ...

  7. LeetCode初级算法--其他01:位1的个数

    LeetCode初级算法--其他01:位1的个数 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net ...

  8. mysql终止当前正在执行的sql语句

    show processlist;找出你要停止的语句然后找出你要终止的语句的idkill 248

  9. 17、Learning and Transferring IDs Representation in E-commerce笔记

    一.摘要 电子商务场景:主要组成部分(用户ID.商品ID.产品ID.商店ID.品牌ID.类别ID等) 传统的编码两个缺陷:如onehot,(1)存在稀疏性问题,维度高(2)不能反映关系,以两个不同的i ...

  10. app安全测试初级

    分析方法:静态分析 主要是利用apktool.dex2jar.jd-gui.smali2dex等静态分析工具对应用进行反编译,并对反编译后的java文件.xml文件等文件进行静态扫描分析,通过关键词搜 ...