模拟赛的题

好神仙啊

题面在这里


之前的Solution很蠢 现在已经update....


题意

有$ n$个商品价格均为$ 1$,您有$ m$种面值的货币,面值为$ C_1..C_m$

每种物品你有$ P$的概率选取,然后你需要选出若干货币购买这些物品

购买商品不存在找零,求浪费在找零上的钱的期望对$ 1e9+7$取模

$ n \leq 10^9 \ m \leq 10^2 \ C_iC_j \leq 10^4$


$Solution $

垃圾模数毁我青春

首先考虑$ m=1$怎么做

枚举购买的物品$ a$

概率为$ P(a)=\binom{n}{a}p^a(1-p)^{n-a}$

显然浪费的钱数$ W(a)$可以$ O(1)$计算

然后发现$ W(a)=W(a \bmod C_1)$,即我们只关心选出物品的数量模$ C_1$意义下的每个值的概率

在模意义下建生成函数

即我们要求的多项式为$(px+1-p)^n $长度为$ C_1$的循环卷积结果

注意这里是循环卷积

暴力卷积的时间复杂度是$ O(10^8·\log n)$

一开始看到时限8s就开开心心的去写了,写完一交爆零看到10组数据,然后看到模数就扔题吃饭去了...

使用拆系数$ FFT$/三模数$ NTT$优化这个卷积即可

时间复杂度$ O(10^4·\log 10^4·\log n)$

然后考虑$ m>1$怎么做

其实吃饭的时候嘴巴bb出来了...吃完饭回机房比赛已经结束了...

反正本来也不可能写得出来的...

首先求$ v=\gcd(C_1,C_2..C_m)$,

根据$ NOIP2017$小凯的疑惑,最大的不能被货币表示出的面值$ kv$应该不超过最大的一对$ C$的乘积

这里好像很感性啊..求评论区给出证明QwQ

因此我们对于选出物品数量不超过$ 10^4$的特殊处理

即对于$ i \leq 10^4$求出恰好选了$ i$个物品的概率$ \binom{n}{i}·p^i·(1-p)^{1-i}$

写了个$ MTT$跑的还挺快...

不过常数依然大就是了...


$ my \ code$

#include<ctime>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#define block 32768
#define p 1000000007
#define rt register int
#define ll long long
using namespace std;
inline ll read(){
ll x=;char zf=;char ch=getchar();
while(ch!='-'&&!isdigit(ch))ch=getchar();
if(ch=='-')zf=-,ch=getchar();
while(isdigit(ch))x=x*+ch-'',ch=getchar();return x*zf;
}
void write(ll y){if(y<)putchar('-'),y=-y;if(y>)write(y/);putchar(y%+);}
void writeln(const ll y){write(y);putchar('\n');}
int k,m,n,x,y,z,cnt,ans,v;
namespace any_module_NTT{
vector<int>R;
const double PI=acos(-1.0);
struct cp{
double x,y;
cp operator +(const cp s)const{return {x+s.x,y+s.y};}
cp operator -(const cp s)const{return {x-s.x,y-s.y};}
cp operator *(const cp s)const{return {x*s.x-y*s.y,x*s.y+y*s.x};}
}w[][];
void FFT(const int n,vector<cp>&A){
A.resize(n);
for(rt i=;i<n;i++)if(i>R[i])swap(A[i],A[R[i]]);
for(rt i=,s=;i<n;i<<=,s++){
for(rt j=;j<n;j+=i<<){
for(rt k=;k<i;k++){
const register cp x=A[j+k],y=w[s][k]*A[i+j+k];
A[j+k]=x+y,A[i+j+k]=x-y;
}
}
}
}
vector<int>Mul(vector<int>&x,vector<int>&y){
int sz=x.size()+y.size()-,lim=;
while(lim<=sz)lim<<=;R.resize(lim);
vector<cp>AB(lim),CD(lim),AC(lim),BC(lim);
for(rt i=;i<lim;i++)R[i]=(R[i>>]>>)|(i&)*(lim>>);
for(rt i=;i<x.size();i++)AB[i].x=((ll)x[i])&,AB[i].y=((ll)x[i])>>;
for(rt i=;i<y.size();i++)CD[i].x=((ll)y[i])&,CD[i].y=((ll)y[i])>>;
FFT(lim,AB);FFT(lim,CD);
for(rt i=;i<lim;i++){
static cp na,nb,nc,nd;const int pl=(lim-)&(lim-i);
na=AB[i]+(cp){AB[pl].x,-AB[pl].y},nb=AB[i]-(cp){AB[pl].x,-AB[pl].y};
nc=CD[i]+(cp){CD[pl].x,-CD[pl].y},nd=CD[i]-(cp){CD[pl].x,-CD[pl].y};
const cp v1={0.5,},v2={,-0.5};
na=na*v1;nb=nb*v2;nc=nc*v1;nd=nd*v2;
AC[pl]=na*nc+na*nd*(cp){,};
BC[pl]=nb*nc+nb*nd*(cp){,};
}
FFT(lim,AC);FFT(lim,BC);
vector<int>ans(v);
for(rt i=;i<sz;i++){
ll v1=AC[i].x/lim+0.5,v2=AC[i].y/lim+BC[i].x/lim+0.5,v3=BC[i].y/lim+0.5;
(ans[i%v]+=(ll)((v3%p<<)+(v2%p<<)+v1)%p)%=p;
}
return ans;
}
}
using namespace any_module_NTT;
vector<int>a[];
bool vis[];int price[],inv[];
int ksm(int x,int y){
int ans=;
for(rt i=y;i;i>>=,x=1ll*x*x%p)if(i&)ans=1ll*ans*x%p;
return ans;
}
int main(){
for(rt i=;(<<i)<=;i++)
for(rt j=;j<(<<i);j++)w[i][j]={cos(PI*j/(<<i)),sin(PI*j/(<<i))};
for(rt T=read();T;T--){
n=read();m=read();int P=read();v=;
memset(vis,,sizeof(vis));vis[]=;
for(rt i=;i<=m;i++){
x=read();
v=__gcd(v,x);
for(rt j=x;j<=;j++)vis[j]|=vis[j-x];
}
cnt=/v;
for(rt i=;i>=;i--)if(vis[i])price[i]=;else price[i]=price[i+]+;
for(rt i=;i<;i++)a[i].resize(v);
a[][]=;a[][%v]=P;a[][]+=(-P);
for(rt i=;(<<i)<=n;i++)a[i]=Mul(a[i-],a[i-]);
vector<int>ret1(v),ret2(v);bool fla=;
for(rt i=;(<<i)<=n;i++)if(n>>i&)if(!fla)ret1=a[i],fla=;else ret1=Mul(ret1,a[i]);
ll ans=;
for(rt i=;i<v;i++)(ans+=1ll*ret1[i]*(v-i)%p)%=p;
inv[]=inv[]=;
for(rt i=;i<cnt;i++)inv[i]=1ll*inv[p%i]*(p-p/i)%p;
for(rt i=,C=;i<cnt&&i<=n;i++){
const int hf=price[i]-((i%v==)?:(v-i%v));
(ans+=1ll*C%p*ksm(P,i)%p*ksm(-P,n-i)%p*hf%p)%=p;
C=1ll*C*(n-i)%p*inv[i+]%p;
}
writeln((ans+p)%p);
}
return ;
}

「2017 山东三轮集训 Day1」Flair的更多相关文章

  1. 【loj6142】「2017 山东三轮集训 Day6」A 结论题+Lucas定理

    题解: 当奇数 发现答案就是C(n,1)^2+C(n,3)^2+...C(n,n)^2 倒序相加,发现就是C(2n,n) 所以答案就是C(2n,n)/2 当偶数 好像并不会证 打表出来可以得到 2.当 ...

  2. 【loj6145】「2017 山东三轮集训 Day7」Easy 动态点分治+线段树

    题目描述 给你一棵 $n$ 个点的树,边有边权.$m$ 次询问,每次给出 $l$ .$r$ .$x$ ,求 $\text{Min}_{i=l}^r\text{dis}(i,x)$ . $n,m\le ...

  3. loj #6138. 「2017 山东三轮集训 Day4」Right

    题目: 题解: 暴力一波 \(SG\) 函数可以发现这么一个规律: \(p\) 为奇数的时候 : \(SG(n) = n \% 2\) \(p\) 为偶数的时候 : \(SG(n) = n \% (p ...

  4. loj #6136. 「2017 山东三轮集训 Day4」Left

    题目: 题解: 我们可以发现所有的交换器都是一个位置连接着下一层左侧的排序网络,另一个位置连着另一侧的排序网络. 而下一层是由两个更低阶的排序网络构成的. 两个网络互不干扰.所以我们可以通过第一行和最 ...

  5. 「2017 山东三轮集训 Day7」Easy

    一棵带边权的树,多次询问 $x$ 到编号为 $[l,r]$ 的点最短距离是多少 $n \leq 100000$ sol: 动态点分治,每层重心维护到所有点的距离 查询的时候在管辖这个点的 log 层线 ...

  6. #6145. 「2017 山东三轮集训 Day7」Easy 动态点分治

    \(\color{#0066ff}{题目描述}\) JOHNKRAM 最近在参加 C_SUNSHINE 举办的聚会. C 国一共有 n 座城市,这些城市由 n−1 条无向道路连接.任意两座城市之间有且 ...

  7. Loj #6142. 「2017 山东三轮集训 Day6」A

    link: https://loj.ac/problem/6142 推完一波式子之后发现求的是:ΣC(N,i)^2, 其中i是偶数. 然后就可以卢卡斯乱搞了,分奇偶和之前的答案合并就好了233. #i ...

  8. LOJ #6145. 「2017 山东三轮集训 Day7」Easy 点分树+线段树

    这个就比较简单了~ Code: #include <cstdio> #include <algorithm> #define N 100004 #define inf 1000 ...

  9. 「2017 山东三轮集训 Day7 解题报告

    「2017 山东三轮集训 Day7」Easy 练习一下动态点分 每个点开一个线段树维护子树到它的距离 然后随便查询一下就可以了 注意线段树开大点... Code: #include <cstdi ...

随机推荐

  1. elementUI el-select 中disabled设置

    <el-select v-model="userForm.roleName" placeholder="请选择用户角色" :disabled=" ...

  2. android开发学习 ------- 关于getSupportFragmentManager()不可用的问题

    在Android开发中,少不了Fragment的运用. 目前在实际运用中,有v-4包下支持的Fragment以及app包下的Fragment,这两个包下的FragmentManager获取方式有点区别 ...

  3. 012_call和apply区别

    一. function fn(a,b) { console.log(this); } fn.call(null,1,2); //call为参数方式 fn.apply(null,[1,2]); //ap ...

  4. Neutron :默认通过 dnsmasq 实现 DHCP 功能----Namespace

    Neutron 提供 DHCP 服务的组件是 DHCP agent. DHCP agent 在网络节点运行上,默认通过 dnsmasq 实现 DHCP 功能.   配置 DHCP agent DHCP ...

  5. php之swoole安装与基本使用

    扩展安装: 参考GitHub地址 安装: 1. 使用PHP官方的PECL工具安装 (初学者) pecl install swoole 2. 从源码编译安装 (推荐) git clone https:/ ...

  6. Laravel 框架结构 以及目录文件解读(学习笔记)

    composer下载Laravel 5.4(由于PHP版本仅7.0,故未下载5.6) composer create-project laravel/laravel your-project-name ...

  7. NOIP2000提高组复赛C 单词接龙

    题目链接:https://ac.nowcoder.com/acm/contest/248/C 题目大意: 略 分析: 注意点:1.前缀和后缀的公共部分应该选最短的.2.如果两个字符串前缀和后缀的公共部 ...

  8. C#中字符串的字面值(转义序列)

    在程序开发中,经常会碰到在字符串中字面值中使用转义序列,下面表格收集了下转义序列的完整列表,以便大家查看引用: 转义序列列表 转义序列 产生的字符 字符的Unicode值 \' 单引号 0x0027 ...

  9. Qt中实现将float类型转换为QString类型

    在使用Qt Creator编程时,难免会用到将float类型转换为QString类型的时候下面是我所有的方法: 1. 将QString类型转化为float类型,很简单 QString data; fl ...

  10. 洛谷P1608路径统计

    题目 这个提示一个简单的最短路计数,除了用数组存上最短路的个数的做法以外,还有可以在得出最短路之后,搜索加剪枝的方法来通过该题. 可以反向搜索用A*的方法来通过,但是这个题的去重十分的恶心,需要一些玄 ...