zoukankan      html  css  js  c++  java
  • 【做题】agc006C

    原文链接https://www.cnblogs.com/cly-none/p/9745177.html

    题意:数轴上有(n)个点,从(1)(n)编号。有(m)个操作,每次操作给出一个编号(i \, 1 < i < n),即把点(i)等概率移动到它关于点(i-1)的对称点或关于点(i+1)的对称点。记顺序执行这(m)个操作为完成1次。问完成(k)次后,所有点的坐标的期望值是多少。

    (n, m leq 10^5, \, k leq 10^{18})

    首先,容易得到一个坐标为x的点,关于坐标为y的点对称后,新点的坐标为2y - x。我们记点i的坐标为(p_i),那么对它操作后得到的新点坐标的期望值就是(frac {2p_{i+1} + 2p_{i-1} -2p_i} {2} = p_{i+1} + p_{i-1} - p_i)

    因为期望有线性性,所以我们能确信,每一次操作就是把点(i)的坐标变为(p_{i+1} + p_{i-1} - p_i),最终答案就是每个点的坐标。

    但我们还是难以解决这个问题。考虑这个性质:

    [egin{eqnarray*} p_{i+1} - (p_{i+1} + p_{i-1} - p_i) &=& p_i - p_{i-1}\ (p_{i+1} + p_{i-1} - p_i) - p_{i-1} &=& p_{i+1} - p_i end{eqnarray*} ]

    我们定义(p'_i = p_i - p_{i-1}),那么,我们发现一次操作就是交换了(p'_i)(p'_{i-1})。因此,这(m)个操作就是对(p')做一个置换。我们把每个环抠出来就能得到重复做(k)次置换之后的结果。最好再通过(p')还原出(p)就好了。

    时间复杂度(O(n))

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 100010;
    typedef long long ll;
    int n,m,p[N],per[N],vis[N],ans[N],lop[N],cnt;
    ll k,val[N],res[N];
    int main() {
      scanf("%d",&n);
      for (int i = 1 ; i <= n ; ++ i)
        scanf("%lld",&val[i]);
      scanf("%d%lld",&m,&k);
      for (int i = 1 ; i <= m ; ++ i)
        scanf("%d",&p[i]);
      for (int i = n ; i >= 1 ; -- i)
        val[i] = val[i] - val[i-1];
      for (int i = 1 ; i <= n ; ++ i)
        per[i] = i;
      for (int i = 1 ; i <= m ; ++ i)
        swap(per[p[i]],per[p[i]+1]);
      for (int i = 1 ; i <= n ; ++ i) {
        if (vis[i]) continue;
        cnt = 0;
        lop[++cnt] = i;
        int pos = per[i];
        while (pos != i) {
          vis[pos] = 1;
          lop[++cnt] = pos;
          pos = per[pos];
        }
        for (int j = 1 ; j <= cnt ; ++ j)
          ans[lop[j]] = lop[(j + k - 1) % cnt + 1];
      }
      for (int i = 1 ; i <= n ; ++ i)
        res[i] = val[ans[i]];
      for (int i = 1 ; i <= n ; ++ i)
        res[i] += res[i-1];
      for (int i = 1 ; i <= n ; ++ i)
        printf("%lld.0
    ",res[i]);
      return 0;
    }
    

    小结:这个特殊性质还是挺难找的。只能说找规律时,考虑差分、前缀和的变化是有用的。

  • 相关阅读:
    mysql 的事件之 Waiting for table metadata lock
    postgresl 10 的逻辑复制 logical replication 之一
    postgresql 物理备份 pg_rman
    pg_waldump pg_xlogdump 的初步使用
    centos 7 添加 aliyun yum 源、epel源
    pg_dump 迁移 prod 环境的 function 到 uat 环境
    POSTGRESQL 11 BETA 1 RELEASED!
    使用 mtools 搭架 mongodb 的自动化日志分析平台
    将xml转换为PHP数组
    php自动获取字符串编码函数mb_detect_encoding
  • 原文地址:https://www.cnblogs.com/cly-none/p/9745177.html
Copyright © 2011-2022 走看看