模拟赛的题

好神仙啊

题面在这里


之前的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. ASP.NET Core 微服务初探[1]:服务发现之Consul

    ASP.NET Core 微服务初探[1]:服务发现之Consul   在传统单体架构中,由于应用动态性不强,不会频繁的更新和发布,也不会进行自动伸缩,我们通常将所有的服务地址都直接写在项目的配置文件 ...

  2. python之shutil

    ''' shutil 用来处理 文件 文件夹 压缩包 的模块 ''' import shutil # 拷贝文件内容 shutil.copyfileobj(open('old.xml', 'r'), o ...

  3. Elastic Stack-Elasticsearch介绍

    一.前言     前篇写了好像没有多少人去看,但是还是要继续,我猜想可能是很多人接触的这块比较少吧,Elasticsearch这块有很多要说的,开始吧. 二.数据库.Elasticsearch选择   ...

  4. JAVA工程师-蚂蚁金服电话面试

    今天5点半接到一个杭州的电话,是蚂蚁金服打来的,当时心里一阵发慌,由于还在上班,就和面试官约定6点下班之后再来.挂完电话,心里忐忑的不行,感觉自己这也没准备好,那也没准备好.剩下半个小时完全没有心思再 ...

  5. JS 优化条件语句的5个技巧

    前言 在使用 JavaScript 的时候,有时我们会处理大量条件语句,这里有5个技巧帮助我们编写更简洁的条件语句. 一.对多个条件使用 Array.includes 例子: function con ...

  6. Spring boot整合ElasticSearch案例分享+bboss

    https://my.oschina.net/bboss/blog/1835601?tdsourcetag=s_pcqq_aiomsg 欢迎观看浏览

  7. PS制作漂亮紫色霓虹灯光文字

    一.新建画布,大小1500 * 950像素,分辨率为300,置入墙壁图像,大小适合. 二.调整图层的色阶,色相/饱和度. 三.新建文字图层,颜色为#a33e88,大小为103,字体为Beon Medi ...

  8. CodeForces Round #545 Div.2

    A. Sushi for Two 代码: #include <bits/stdc++.h> using namespace std; ; ; int a[maxn], vis[maxn]; ...

  9. 关于vue打包是因代码校验报错

    单个文件中: 1./* eslint - disable */ 2./* eslint-disable no-new */ 当然也支持全局: 3.bulid > webpack.base.con ...

  10. [官网]Using PuTTY

    Previous | Contents | Next Chapter 3: Using PuTTY Section 3.1: During your session Section 3.1.1: Co ...