神仙题

LOJ #6509


题意

给定一棵树,点权为0/1,每次随机一个点(可能和之前所在点相同)走到该点并将其点权异或上1

求期望的移动距离使得所有点点权相同


题解

根本不会解方程

容易发现如果一个点不是最后一次被走到,就会随机下一个点并走过去

即如果我们能求出每个点非最后一次走到的期望次数,就可以算出答案

由于完全随机,初始相同颜色的点非最后一次走到的次数相同

设$ f_{i,0/1}$表示在有$ i$个1的时候,0/1非最后一次走到的期望次数

很艰难的列出方程如下

$$ f_{i,0} = \frac{i}{n} f_{i-1, 0} + \frac{n-i-1}{n} f_{i+1, 0} + \frac{1}{n} f_{i+1,1} + \frac{1}{n} $$
$$ f_{i,1} = \frac{n-i}{n} f_{i+1, 1} + \frac{i-1}{n} f_{i-1, 1} + \frac{1}{n} f_{i-1,0} + \frac{1}{n}$$

注意由于记录的是非最后一次走到,需要特判边界

即当前已经有$ n-1$个黑色时将最后一个白点翻成黑点不算入期望次数,黑点翻成白点同理

然后可以暴力高消了

但这个方程有很多优美的性质

不容易发现$ f_{i+1,1}$只和$ f_{i,1}$和$ f_{i-1,0/1}$有关

因此如果知道前面的信息就可以推出$ f_{i+1,1}$

同理再借助$ f_{i+1,1}$就能推出$ f_{i+1,0}$

因此我们设$ f_{1,0}=x,f_{1,1}=y$并把所有$ f_{x,0/1}$用$ Ax+By+c$表示

然后在最后联立两个方程解出$ x,y$就做完了

边界细节真**多


代码

#include<ctime>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#define p 1000000007
#define rt register int
#define ll long long
using namespace std;
inline ll read(){
ll x=;char zf=;char ch=getchar();
while(ch!='-'&&!isdigit(ch))ch=getchar();
if(ch=='-')zf=-,ch=getchar();
while(isdigit(ch))x=x*+ch-'',ch=getchar();return x*zf;
}
void write(ll y){if(y<)putchar('-'),y=-y;if(y>)write(y/);putchar(y%+);}
void writeln(const ll y){write(y);putchar('\n');}
int k,m,n,x,y,z,cnt;
struct fc{
ll a,b,c;//ax+by+c
fc operator +(const fc s)const{return {a+s.a,b+s.b,c+s.c};}
fc operator -(const fc s)const{return {a-s.a,b-s.b,c-s.c};}
fc operator *(const int s)const{return {a*s%p,b*s%p,c*s%p};}
fc operator +(const int s)const{return {a,b,c+s};}
fc operator -(const int s)const{return {a,b,c-s};}
}f[][];
int inv[],fa[],size[];ll ans[];
char c[];
vector<int>E[];
int ksm(int x,int y=p-){
x%=p;
while(x<)x+=p;
int ans=;
for(rt i=y;i;i>>=,x=1ll*x*x%p)if(i&)ans=1ll*ans*x%p;
return ans;
}
void dfs(int x){
size[x]=;
for(auto i:E[x]){
dfs(i);
size[x]+=size[i];
ans[x]+=ans[i]+size[i];
}
}
void dfs2(int x){
if(x!=)ans[x]=ans[fa[x]]+n-size[x]*;
for(auto i:E[x])dfs2(i);
}
int main(){
n=read();scanf("%s",c+);int sum=;
for(rt i=;i<=n;i++)sum+=(c[i]=='');
inv[]=inv[]=;
for(rt i=;i<=n;i++)inv[i]=1ll*inv[p%i]*(p-p/i)%p;
f[][].a=;f[][].b=;
for(rt i=;i<=n-;i++){
if(i==)f[i+][]=(f[i][]*n-f[i-][]*(i-)-f[i-][])*inv[n-i];
else f[i+][]=(f[i][]*n-f[i-][]*(i-)-f[i-][]-)*inv[n-i];
f[i+][]=(f[i][]*n-f[i-][]*i-f[i+][]-)*inv[n-i-];
}
fc x=f[n][];
fc a0=f[n-][]*(n-)-f[n-][]*n,a1=f[n-][]*(n-)-f[n-][]*n+f[n-][]+;
ll a=a0.a,b=a0.b,C=a0.c,d=a1.a,e=a1.b,F=a1.c;
int invd=ksm(d);
int Y=(F%p*invd%p*a%p-C)%p*ksm(b%p-e%p*invd%p*a%p)%p;
int X=(b%p*Y%p+C%p)*ksm(a)%p;X=-X;
int B=(f[sum][].a*X+f[sum][].b*Y+f[sum][].c)%p+inv[n];
int W=(f[sum][].a*X+f[sum][].b*Y+f[sum][].c)%p+inv[n];
B%=p;W%=p;B=1ll*B*inv[n]%p,W=1ll*W*inv[n]%p;
for(rt i=;i<=n;i++){
fa[i]=read();
E[fa[i]].push_back(i);
}
dfs();dfs2();ll ret=;
for(rt i=;i<=n;i++)if(c[i]=='')(ret+=1ll*B*(ans[i]%p)%p)%=p;
else (ret+=1ll*W*(ans[i]%p)%p)%=p;
cout<<(ret+p)%p;
return ;
}

LOJ #6509. 「雅礼集训 2018 Day7」C的更多相关文章

  1. Loj #6503. 「雅礼集训 2018 Day4」Magic

    Loj #6503. 「雅礼集训 2018 Day4」Magic 题目描述 前进!前进!不择手段地前进!--托马斯 · 维德 魔法纪元元年. 1453 年 5 月 3 日 16 时,高维碎片接触地球. ...

  2. 【刷题】LOJ 6041 「雅礼集训 2017 Day7」事情的相似度

    题目描述 人的一生不仅要靠自我奋斗,还要考虑到历史的行程. 历史的行程可以抽象成一个 01 串,作为一个年纪比较大的人,你希望从历史的行程中获得一些姿势. 你发现在历史的不同时刻,不断的有相同的事情发 ...

  3. loj 6043「雅礼集训 2017 Day7」蛐蛐国的修墙方案

    loj 爆搜? 爆搜! 先分析一下,因为我们给出的是一个排列,然后让\(i\)给\(p_i\)连边,那么我们一定会得到若干个环,最后要使得所有点度数为1,也就是这些环有完备匹配,那么最后一定全是偶环. ...

  4. LOJ #6041. 「雅礼集训 2017 Day7」事情的相似度

    我可以大喊一声这就是个套路题吗? 首先看到LCP问题,那么套路的想到SAM(SA的做法也有) LCP的长度是它们在parent树上的LCA(众所周知),所以我们考虑同时统计多个点之间的LCA对 树上问 ...

  5. loj#6041. 「雅礼集训 2017 Day7」事情的相似度(SAM set启发式合并 二维数点)

    题意 题目链接 Sol 只会后缀数组+暴躁莫队套set\(n \sqrt{n} \log n\)但绝对跑不过去. 正解是SAM + set启发式合并 + 二维数点/ SAM + LCT 但是我只会第一 ...

  6. LOJ #6042. 「雅礼集训 2017 Day7」跳蚤王国的宰相

    我可以大喊一声这就是个思博题吗? 首先如果你能快速把握题目的意思后,就会发现题目就是让你求出每个点要成为树的重心至少要嫁接多少边 先说一个显然的结论,重心的答案为\(0\)(废话) 然后我们考虑贪心处 ...

  7. LOJ #6043. 「雅礼集训 2017 Day7」蛐蛐国的修墙方案

    我可以大喊一声这就是个SB题吗? 首先讲一句如果你像神仙CXR一样精通搜索你就可以得到\(80pts\)(无Subtask)的好成绩 我们考虑挖掘一下题目的性质,首先发现这是一个置换,那么我们发现这的 ...

  8. LOJ#6503.「雅礼集训 2018 Day4」Magic[容斥+NTT+启发式合并]

    题意 \(n\) 张卡牌 \(m\) 种颜色,询问有多少种本质不同的序列满足相邻颜色相同的位置数量等于 \(k\). 分析 首先本质不同不好直接处理,可以将同种颜色的卡牌看作是不相同的,求出答案后除以 ...

  9. LOJ#6504. 「雅礼集训 2018 Day5」Convex(回滚莫队)

    题面 传送门 题解 因为并不强制在线,我们可以考虑莫队 然而莫队的时候有个问题,删除很简单,除去它和前驱后继的贡献即可.但是插入的话却要找到前驱后继再插入,非常麻烦 那么我们把它变成只删除的回滚莫队就 ...

随机推荐

  1. In action "Setting JDBC driver jar location unix [Set a variable]" (screen "Select a Database [Configurable banner form]"), property "Script":

    java.lang.Exception: JDBC Driver Jar not found. Looking for: /u01/oracle/GG_Director/ERROR: Unresolv ...

  2. [原创]一款小巧、灵活的Java多线程爬虫框架(AiPa)

    1.简介 AiPa 是一款小巧,灵活,扩展性高的多线程爬虫框架. AiPa 依赖当下最简单的HTML解析器Jsoup. AiPa 只需要使用者提供网址集合,即可在多线程下自动爬取,并对一些异常进行处理 ...

  3. 多线程手写Future模式

    future模式 在进行耗时操作的时候,线程直接阻塞,我们需要优化这样的代码,让他再启动一个线程,不阻塞.可以执行下面的代码. 这个时候我们就用到了未来者模式 future设计类 只有一个方法 pub ...

  4. 我对DFS的理解

    我对DFS的理解 [何为DFS] 深度优先搜索(Depth-First-Search),简称DFS.是一种常见搜索算法.其方法是从原点不断一条路扩散,当无路可走时回退来走下一条路,直至找到目标或遍历. ...

  5. MarkDownPad2基本语法

    一.换行和空格   (1)换行   行尾加两个空格   (2)空格     二.标题   在#后跟个空格再写文字,一个#是一级标题,两个#是二级标题,以此类推,支持六级标题.   示例: # 一级标题 ...

  6. setInterval的简单理解和实验

    setInterval的用法 setInterval(fn_name,time_num); setInterval(fn_name,time_num,这里是函数参数); 意思是,现在不执行fn_nam ...

  7. JS继承以及继承的几种实现方式总结

    传统面向对象语言:继承是类与类之间的关系. 而在js中由于es6之前没有类的概念,所以继承是对象与对象之间的关系. 在js中,继承就是指使一个对象有权去访问另一个对象的能力. 比如:比如对象a能够访问 ...

  8. https 自签名SSL证书

    介绍 TLS或称传输层安全性,及其前身SSL(代表安全套接字层)是用于将正常流量包装在受保护的加密包装中的Web协议. 使用这种技术,服务器可以在服务器和客户端之间安全地发送流量,而不会被外部各方拦截 ...

  9. 在线SQL

    有时候为了简单测试一下SQL语法,自己机器上没有安装,可使用在线的SQL环境. 我找到了两个: https://rextester.com/l/sql_server_online_compiler ( ...

  10. bzoj 1926: [Sdoi2010]粟粟的书架 (主席树+二分)

    链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1926 题面; 1926: [Sdoi2010]粟粟的书架 Time Limit: 30 Se ...