Atcoder Grand 006 C-Rabbit Exercise
题意:
数轴上有n只兔子,第i只兔子的坐标为xi。
有一组操作,这组操作的第i个操作是要让第ai只兔子等概率的跳到自己关于第ai+1或第ai-1只兔子的对称点。
进行K组操作,求每只兔子最后坐标的期望值。
当第一只兔子i跳完,它的位置的期望是x[i+1]+x[i−1]−x[i]。
然后我们发现当有其他一只兔子j要以i为对称轴跳跃时j跳完坐标的期望就是以i的期望坐标为对称轴跳跃到的坐标。
所以每次相当于让x[i]=x[i+1]+x[i−1]−x[i]。
我们维护差分序列,每次相当于交换了相邻两个数。
先做完一组,得到了一个排列,之后连边找环,就能知道跳k组后的位置了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | #include<bits/stdc++.h> #define N 100005 #define int long long using namespace std; int n,m,x[N],a[N],p[N],s[N],cnt; long long k; int be[N],num[N],v[N]; vector< int >q[N]; void dfs( int x, int dep) { num[x]=dep;v[x]=1;be[x]=cnt; q[cnt].push_back(x); if (!v[p[x]])dfs(p[x],dep+1); } signed main() { memset (v,0, sizeof (v)); cin>>n; for ( int i=1;i<=n;i++)cin>>x[i]; for ( int i=1;i<n;i++)s[i]=x[i+1]-x[i]; cin>>m>>k; for ( int i=1;i<n;i++)p[i]=i; for ( int i=1;i<=m;i++){cin>>a[i];swap(p[a[i]],p[a[i]-1]);} for ( int i=1;i<n;i++) if (!v[i])cnt++,dfs(i,0); cout<<x[1]<<endl; int now=x[1]; for ( int i=1;i<n;i++) { now+=s[q[be[i]][(num[i]+k)%q[be[i]].size()]]; cout<<now<<endl; } return 0; } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步