zoukankan      html  css  js  c++  java
  • AGC600 C Rabbit Exercise —— 置换

    题目:https://agc006.contest.atcoder.jp/tasks/agc006_c

    考虑 ( i ) 号兔子移动后位置的期望,是 ( x_{i+1} + x_{i-1} - x_{i} )

    然后作差分,发现按顺序移动一次,实际上是交换了 ( d_{a_{i}} ) 和 ( d_{a_{i}+1} )

    于是可以先处理出移动一次的置换,然后快速幂;

    而这是 ( nlogn ) 的做法,还可以找循环来做到 ( O(n) ) ,可见 Narh 的博客;

    就写了 ( nlogn ) 的做法。

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    typedef double db;
    int const xn=1e5+5;
    int n,m,a[xn],t[xn],p[xn];
    db d[xn],tt[xn];
    ll k;
    ll rd()
    {
      ll ret=0,f=1; char ch=getchar();
      while(ch<'0'||ch>'9'){if(ch=='-')f=0; ch=getchar();}
      while(ch>='0'&&ch<='9')ret=ret*10+ch-'0',ch=getchar();
      return f?ret:-ret;
    }
    void pw()
    {
      memcpy(t,p,sizeof t);
      for(int i=1;i<=n;i++)p[i]=t[t[i]];//n
    }
    void ch()
    {
      memcpy(tt,d,sizeof tt);
      for(int i=1;i<=n;i++)d[i]=tt[p[i]];
    }
    int main()
    {
      n=rd(); db x=0,pr=0;
      for(int i=1;i<=n;i++)scanf("%lf",&x),d[i]=x-pr,pr=x;
      m=rd(); k=rd();
      for(int i=1;i<=m;i++)a[i]=rd();
      for(int i=1;i<=n;i++)p[i]=i;
      for(int i=1;i<=m;i++)swap(p[a[i]],p[a[i]+1]);
      for(;k;k>>=1ll,pw())if(k&1)ch();
      db pos=0;
      for(int i=1;i<=n;i++)
        pos+=d[i],printf("%.1f
    ",pos);
      return 0;
    }
  • 相关阅读:
    uva 1391(2-SAT)
    uva 1146(2-SAT+二分判断)
    uva 12167(强连通分支)
    uva 11324(强连通分支+DAG)
    Codeforces Round #227 (Div. 2) 解题报告
    uva 10319(2-SAT)
    uva 610(割边)
    uva 11504(强连通分支)
    测试:网页测试,入门面试题
    测试:安装包的测试
  • 原文地址:https://www.cnblogs.com/Zinn/p/10057651.html
Copyright © 2011-2022 走看看