zoukankan      html  css  js  c++  java
  • [AGC006C] Rabbit Exercise

    link

    题目翻译

    数轴上有 $n$ 个点,每次可以选择点 $x$ ,从 $x-1$ 或 $x+1$ 中等概率选择一个点,作关于此点的对称点,共 $k$ 轮,问每个点所在位置的期望。

    $solution:$

    若此刻选择 $i$ 点移动,设 $f_i$ 表示 $i$ 点的期望,则 $f_i=f_{i-1}+f_{i+1}-f_i$ ,暴力 $dp$ ,时间复杂度 $O(nk)$ ,无法通过此题。

    考虑差分,设 $d_i=f_i-f_{i-1}$ ,若 $i$ 点移动后, $d_i=f_i-f_{i-1}=f_{i-1}+f_{i+1}-f_i-f_{i-1}=f_{i+1}-f_{i}\d_{i+1}=f_{i+1}-f_i=f_{i+1}-(f_{i-1}+f_{i+1}-f_i)=f_i-f_{i+1}$ 。

    所以当 $i$ 点移动的本质是交换 $d_i,d_{i+1}$ ,设 $g_{i,j}$ 表示 $i$ 号经过 $2^j$ 次后的差分数组,直接倍增维护即可。

    时间复杂度 $O(log k)$

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #define int long long
    using namespace std;
    inline int read(){
        int f=1,ans=0;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();}
        return f*ans;
    }
    const int MAXN=100001;
    int m,k,ans,n,x[MAXN],d[MAXN],a[MAXN],fa[MAXN][61],p[MAXN];
    signed main(){
    //    freopen("2.in","r",stdin);
        n=read();
        for(int i=1;i<=n;i++) x[i]=read(),d[i]=i,p[i]=x[i]-x[i-1];
        m=read(),k=read();
        for(int i=1;i<=m;i++) a[i]=read(),swap(d[a[i]],d[a[i]+1]);
        for(int i=1;i<=n;i++) fa[i][0]=d[i];
        for(int j=1;j<=60;j++)
            for(int i=1;i<=n;i++) fa[i][j]=fa[fa[i][j-1]][j-1];
        for(int i=1;i<=n;i++){
            int res=i;
            int K=k;
            for(int j=60;j>=0;j--) if(K-(1ll<<j)>=0) K-=(1ll<<j),res=fa[res][j];
            ans+=p[res];
            printf("%.1f
    ",(double)ans);
        }return 0;
    }/*
    3
    1 -1 1
    2 2
    2 2
    */
    View Code
  • 相关阅读:
    idea新建web项目
    wampserver的MySQL和本机MySQL冲突导致空密码登录报错
    while-else if
    格式化输出
    Zookeeper
    仿真手写Spring核心原理v1.0
    各设计模式总结与对比
    装饰者模式和观察者模式
    模板模式和适配器模式
    委派模式和策略模式
  • 原文地址:https://www.cnblogs.com/si-rui-yang/p/11199346.html
Copyright © 2011-2022 走看看