4.5考试

众所周知,只要考数学和概率与期望,lyh就会挂大分,尤其是概率与期望……

考试总结

一、答题策略

考场不知道咋回事,没有想出来B题就挺可惜的……

看到概率与期望大脑都是蒙的……根本没想策略,导致答题时非常慌张。

嗯,下次答题时还是不能心态炸掉……

二、题解

A.[JLOI2014] 聪明的燕姿

纯数学题。

根据整数的唯一分解定理(\(x=\prod\limits_{i=1}^kp_i^{a_i}\))和约数和公式(\(S=\prod\limits_{i=1}^k(\sum\limits_{j=0}^{a_i}p_i^j)\)),我们可以尝试暴搜。

\(dfs(x,y,s)\) 表示还有 \(x\) 可以分解,枚举到了第 \(y\) 个质数,当前的答案是多少。

\(x=p+1\) 时,\(ans\) 可以是 \(s\times p\)

\(x=1\) 时,\(ans\) 可以是 \(s\)

时间复杂度没细算,是 \(O(能过)\)

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e5+5;
int n,m,k,v[N];
ll p[N],ans[N];
int pr(ll x){
    if(x==1) return 0;
    for(int i=2;i*i<=x;i++)
        if(x%i==0) return 0;
    return 1;
}void dfs(ll x,int y,ll s){
    if(x==1){
        ans[++k]=s;
        return;
    }if(pr(x-1)&&x>p[y])
        ans[++k]=s*(x-1);
    for(int i=y;p[i]*p[i]<=x;i++){
        ll l=p[i],j=p[i]+1;
        for(;j<=x;l*=p[i],j+=l)
            if(x%j==0) dfs(x/j,i+1,s*l);
    }
}int main(){
    for(int i=2;i<N;i++){
        if(!v[i]) p[++n]=i;
        for(int j=1;j<=n&&p[j]*i<N;j++){
            v[i*p[j]]=1;
            if(i%p[j]==0) break;
        }
    }while(cin>>m){
        dfs(m,1,1);
        sort(ans+1,ans+k+1);
        cout<<k<<"\n";
        for(int i=1;i<=k;i++)
            cout<<ans[i]<<" ";
        if(k) k=0,cout<<"\n";
    }return 0;
}

B.luogu P4550

概率与期望题。

先考虑次数的期望。设 \(f_i\) 表示抽到了 \(i\) 种不同邮票的期望次数,则有:

\[f_i=\frac{n-i}{n}f_{i+1}+\frac{i}{n}f_i+1 \]

化简得:

\[f_i=f_{i+1}+\frac{n}{n-i} \]

\(g_i\) 表示抽到了 \(i\) 种不同邮票的期望钱数,则有:

\[g_i=\frac{i}{n}(g_i+f_i+1)+\frac{n-i}{n}(g_{i+1}+f_{i+1}+1) \]

化简得:

\[g_i=\frac{i}{n-i}f_i+g_{i+1}+f_{i+1}+\frac{n}{n-i} \]

时间复杂度 \(O(n)\)

#include<bits/stdc++.h>
#define ll long long
using namespace std;
double n,dp[10005],f[10005];
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    cin>>n;
    for(int i=n-1;~i;i--){
        dp[i]=dp[i+1]+n/(n-i);
        f[i]=(double)i/(n-i)*dp[i]+f[i+1]+dp[i+1]+n/(n-i);
    }printf("%.2lf",f[0]);
    return 0;
}

C.[HAOI2018] 苹果树

难于上青天……

考虑拆开来考虑每一条边的贡献。

答案即为 \(\sum\operatorname{size}(i)(n-\operatorname{size}(i))\)

\(dp_{i,j,k}\) 表示子树根节点为 \(i\),决策到 \(k\) 号点,\(i\) 的子树大小为 \(j\),则有:

\[dp_{i,j,k}=j\times dp_{i,j-1,k-1}+(k-j-1)\times dp_{i,j,k-1} \]

于是 \(i\) 就被我们抛弃了。

所以我们只需要

\[dp_{j,k}=j\times dp_{j-1,k-1}+(k-j-1)\times dp_{j,k-1} \]

即可。时间复杂度 \(O(n^2)\)

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n,p,dp[2005][2005],jc[2005],ans;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    cin>>n>>p;
    jc[0]=1;
    for(ll i=1;i<=n;i++){
        jc[i]=jc[i-1]*i%p;
        for(ll j=1;j<=i;j++)
            dp[i][j]=(dp[i-1][j-1]*j%p+dp[i-1][j]*(i-j-1)%p)%p;
        dp[i][1]=(dp[i][1]+jc[i])%p;
    }for(ll i=1;i<=n;i++)
        ans=(ans+dp[n][i]*i*(n-i)%p)%p;
    cout<<ans;
    return 0;
}

D.[HAOI2012] 高速公路

由于实际上只有 \(n-1\) 条公路,所以每次询问的 \(r=r-1\)

容易看得出,每一个询问的答案为:

\[\dfrac{\sum\limits_{i=l}^r\sum\limits_{j=l}^{r}dis_{i,j}}{C_{r-l+1}^2} \]

设分子为 \(ans\),则:

\[ans=\sum\limits_{i=l}^ra_i(r-i+1)(i-l+1)\\ =\sum\limits_{i=l}^ra_ii^2+a_ii(l+r)+a_i(r-l+1-lr)\]

\(s1=a_i,s_2=a_ii,s_3=a_ii^2\)

\[ans=\sum\limits_{i=l}^r s1(r-l+1-lr)+s2(l+r)+s3 \]

\(s1,s2,s3\) 可以用线段树维护,在修改 \(s2,s3\) 时,需要统计 \(s4=\sum i,s5=\sum i^2\)

时间复杂度 \(O(n\log n)\)

#include<bits/stdc++.h>
#define int long long
using namespace std;
int gcd(int x,int y){
    if(!y) return x;
    return gcd(y,x%y);
}const int N=4e5+5;
int n,m,lf[N],rt[N],lb[N];
int a[N],b[N],c[N],d[N],e[N];
int s1,s2,s3;
void down(int x,int k){
    a[x]+=(rt[x]-lf[x]+1)*k;
    b[x]+=k*d[x];
    c[x]+=k*e[x];
    lb[x]+=k;
}void pushdown(int x){
    if(!lb[x]) return;
    down(x*2,lb[x]);
    down(x*2+1,lb[x]);
    lb[x]=0;
}void build(int l,int r,int x){
    lf[x]=l,rt[x]=r;
    if(l==r){
        d[x]=l;
        e[x]=l*l;
        return;
    }int mid=(l+r)/2;
    build(l,mid,x*2);
    build(mid+1,r,x*2+1);
    d[x]=d[x*2]+d[x*2+1];
    e[x]=e[x*2]+e[x*2+1];
}void chg(int l,int r,int x,int v){
    if(l<=lf[x]&&rt[x]<=r){
        down(x,v);
        return;
    }pushdown(x);
    int mid=(lf[x]+rt[x])/2;
    if(mid>=l) chg(l,r,x*2,v);
    if(mid<r) chg(l,r,x*2+1,v);
    a[x]=a[x*2]+a[x*2+1];
    b[x]=b[x*2]+b[x*2+1];
    c[x]=c[x*2]+c[x*2+1];
}void que(int l,int r,int x){
    if(l<=lf[x]&&rt[x]<=r){
        s1+=a[x];
        s2+=b[x];
        s3+=c[x];
        return;
    }pushdown(x);
    int mid=(lf[x]+rt[x])/2;
    if(mid>=l) que(l,r,x*2);
    if(mid<r) que(l,r,x*2+1);
}signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    cin>>n>>m;
    build(1,n-1,1);
    while(m--){
        char c;
        cin>>c;
        if(c=='C'){
            int l,r,v;
            cin>>l>>r>>v;
            chg(l,r-1,1,v);
            continue;
        }int l,r;
        s1=s2=s3=0;
        cin>>l>>r;
        que(l,r-1,1);
        int x=(r-r*l)*s1+(r+l-1)*s2-s3;
        int y=(r-l+1)*(r-l)/2;
        int g=gcd(x,y);
        cout<<x/g<<"/"<<y/g<<"\n";
    }return 0;
}
posted @ 2024-04-06 09:18  长安一片月_22  阅读(10)  评论(0编辑  收藏  举报