bzoj3992: [SDOI2015]序列统计

2024-04-02 10:48

本文主要是介绍bzoj3992: [SDOI2015]序列统计,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

传送门:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3992

思路:M是一个质数,问题又是求乘积,于是我们就可以想到利用M的原根g把问题变成求和(我怎么想不到啊。。。)

根据原根的性质,我们可以把1到M-1中的数i表示为(g^b[i])%M,且指数互不相同

那么X就可以表示成(g^b[x])%M

问题就转化为:然后问题转化成了在序列b中,选出n个数(一个数可以取多次),且它们的和s满足s=b[x]

这个问题我们可以用母函数+NTT解决,答案就是多项式的b[x]次项的系数

因为n很大,所以再套一个快速幂即可

#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int mod=(479<<21)+1,G=3,maxn=17000;
int n,k,sum,m,inv_G,inv_N,T[maxn],vis[maxn],tim,N,rev[maxn],pos[maxn],root;int qpow(int a,int b){int res=1;for (;b;b>>=1){if (b&1) res=1ll*res*a%mod;a=1ll*a*a%mod;}return res;
}bool check(int x){int now=1;++tim;for (int i=1;i<n;i++,now=now*x%n){if (vis[now]==tim) return 0;vis[now]=tim;}return 1;
}int rever(int x){int res=0,len=N;while (len--) res<<=1,res^=(x&1),x>>=1;return res;}
int findroot(){for (int i=2;i<=n;i++) if (check(i)) return i;}struct DFT{int a[maxn];void ntt(int op){for (int i=0;i<N;i++) if (rev[i]>i) swap(a[rev[i]],a[i]);int g=op==1?G:inv_G;for (int sz=2;sz<=N;sz<<=1){int t=qpow(g,(mod-1)/sz);for (int bg=0;bg<N;bg+=sz)for (int po=bg,w=1;po<bg+(sz>>1);po++){int x=a[po],y=1ll*a[po+(sz>>1)]*w%mod;a[po]=(x+y)%mod,a[po+(sz>>1)]=(x-y+mod)%mod;w=1ll*w*t%mod;}}if (op==-1) for (int i=0;i<N;i++) a[i]=1LL*a[i]*inv_N%mod;}
}a,b;void qpow(){b.a[0]=1;for (;k;k>>=1){a.ntt(1);if (k&1){b.ntt(1);for (int i=0;i<N;i++) b.a[i]=1ll*b.a[i]*a.a[i]%mod;b.ntt(-1);for (int i=N-1;i>=n-1;i--) b.a[i-n+1]=(b.a[i-n+1]+b.a[i])%mod,b.a[i]=0;//因为是在mod m(代码里的n)的条件下进行的,所以要把和超过m的后半部分的答案加到前半部分去,而不是简单的清空}for (int i=0;i<N;i++) a.a[i]=1ll*a.a[i]*a.a[i]%mod;a.ntt(-1);for (int i=N-1;i>=n-1;i--) a.a[i-n+1]=(a.a[i-n+1]+a.a[i])%mod,a.a[i]=0;}
}int main(){inv_G=qpow(G,mod-2);scanf("%d%d%d%d",&k,&n,&sum,&m);for (int i=1;i<=m;i++) scanf("%d",&T[i]);N=(int)ceil(log2(n))+1;for (int i=0;i<(1<<N);i++) rev[i]=rever(i);N=1<<N,inv_N=qpow(N,mod-2),root=findroot();for (int i=0,res=1;i<n-1;i++) pos[res]=i,res=res*root%n;for (int i=1;i<=m;i++) if (T[i]) a.a[pos[T[i]]]++;qpow(),printf("%d\n",b.a[pos[sum]]);return 0;
}


这篇关于bzoj3992: [SDOI2015]序列统计的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/869781

相关文章

SQL Server跟踪自动统计信息更新实战指南

《SQLServer跟踪自动统计信息更新实战指南》本文详解SQLServer自动统计信息更新的跟踪方法,推荐使用扩展事件实时捕获更新操作及详细信息,同时结合系统视图快速检查统计信息状态,重点强调修... 目录SQL Server 如何跟踪自动统计信息更新:深入解析与实战指南 核心跟踪方法1️⃣ 利用系统目录

Spring的RedisTemplate的json反序列泛型丢失问题解决

《Spring的RedisTemplate的json反序列泛型丢失问题解决》本文主要介绍了SpringRedisTemplate中使用JSON序列化时泛型信息丢失的问题及其提出三种解决方案,可以根据性... 目录背景解决方案方案一方案二方案三总结背景在使用RedisTemplate操作redis时我们针对

在Linux终端中统计非二进制文件行数的实现方法

《在Linux终端中统计非二进制文件行数的实现方法》在Linux系统中,有时需要统计非二进制文件(如CSV、TXT文件)的行数,而不希望手动打开文件进行查看,例如,在处理大型日志文件、数据文件时,了解... 目录在linux终端中统计非二进制文件的行数技术背景实现步骤1. 使用wc命令2. 使用grep命令

详解如何使用Python从零开始构建文本统计模型

《详解如何使用Python从零开始构建文本统计模型》在自然语言处理领域,词汇表构建是文本预处理的关键环节,本文通过Python代码实践,演示如何从原始文本中提取多尺度特征,并通过动态调整机制构建更精确... 目录一、项目背景与核心思想二、核心代码解析1. 数据加载与预处理2. 多尺度字符统计3. 统计结果可

利用Python实现时间序列动量策略

《利用Python实现时间序列动量策略》时间序列动量策略作为量化交易领域中最为持久且被深入研究的策略类型之一,其核心理念相对简明:对于显示上升趋势的资产建立多头头寸,对于呈现下降趋势的资产建立空头头寸... 目录引言传统策略面临的风险管理挑战波动率调整机制:实现风险标准化策略实施的技术细节波动率调整的战略价

PostgreSQL 序列(Sequence) 与 Oracle 序列对比差异分析

《PostgreSQL序列(Sequence)与Oracle序列对比差异分析》PostgreSQL和Oracle都提供了序列(Sequence)功能,但在实现细节和使用方式上存在一些重要差异,... 目录PostgreSQL 序列(Sequence) 与 oracle 序列对比一 基本语法对比1.1 创建序

Pandas中统计汇总可视化函数plot()的使用

《Pandas中统计汇总可视化函数plot()的使用》Pandas提供了许多强大的数据处理和分析功能,其中plot()函数就是其可视化功能的一个重要组成部分,本文主要介绍了Pandas中统计汇总可视化... 目录一、plot()函数简介二、plot()函数的基本用法三、plot()函数的参数详解四、使用pl

Pandas统计每行数据中的空值的方法示例

《Pandas统计每行数据中的空值的方法示例》处理缺失数据(NaN值)是一个非常常见的问题,本文主要介绍了Pandas统计每行数据中的空值的方法示例,具有一定的参考价值,感兴趣的可以了解一下... 目录什么是空值?为什么要统计空值?准备工作创建示例数据统计每行空值数量进一步分析www.chinasem.cn处

Mysql如何将数据按照年月分组的统计

《Mysql如何将数据按照年月分组的统计》:本文主要介绍Mysql如何将数据按照年月分组的统计方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录mysql将数据按照年月分组的统计要的效果方案总结Mysql将数据按照年月分组的统计要的效果方案① 使用 DA

C++从序列容器中删除元素的四种方法

《C++从序列容器中删除元素的四种方法》删除元素的方法在序列容器和关联容器之间是非常不同的,在序列容器中,vector和string是最常用的,但这里也会介绍deque和list以供全面了解,尽管在一... 目录一、简介二、移除给定位置的元素三、移除与某个值相等的元素3.1、序列容器vector、deque