考场

\(65+5+0\),并列 rk2

最高分 \(55+10+10\)

T1:等比数列可以写作 \(q^kx\),发现 \(q\le1000\) 且有一档分为 \(a_i\le100\),想到 \(2^{60}>10^{18}\),即等比数列的长度最多为 \(59\),这样枚举的区间就从 \(n^2\) 下降到了 \(60n\)。对于每个区间,排序后枚举 \(q\),通过预处理 \(q\) 的次幂大力剪枝,复杂度不明。写了很久,最终有RE有TLE。

T3:虽然以前学过欧拉路,但之后再没写过,忘得只剩下题目给出的定义。发现自己会的暴力是 \(O(2^{n(n-1)/2}m),(m为边数)\),没有分(其实可以打表)手玩小数据无果就放弃了。hkh的20pts是正解,但把某个快速幂的地方写成了 1ll<<

T2:猜到是树形DP,但只剩下1h了,加上部分分有40pts,就决定放弃写正解。先写了菊花图的分,暴力写挂了。知道最后10min才意识到我的写法(边dfs边枚举重儿子)会在枚举完重儿子后只能在这个子树里走,导致有些答案统计不上。wcr的DP是假的,过了二叉树的点和其他一些点,45pts

sol

序列

如果要对区间排序,复杂度至少是 \(O(60n)\),再加上判断是否等比,肯定过不去。因此正解利用等比数列的性质规避了排序。

等比数列的公比开 \(n\) 次根也一定是该数列的公比

等比数列中任意两数之商是公比的 \(n\) 次

因此枚举 \(q\),记录下每个数开 \(n\) 次根的最小整数是多少,然后直接用两个原数列中相邻的数就可以确定公比(公比越小越容易加入数)

ycx依据 \(q\) 很小,有另一种做法(但时间复杂度劣)

code
const int N = 1e5+5;
const LL X = 1000000000000000000ll;
int n;
LL a[N]; int ans;
map<LL,int> minq;
map<LL,bool> vis; int main() {
For(i,2,1000)
for(LL j = 1; j <= X/i; j *= i)
if( !minq[j*i] ) minq[j*i] = i; // 记录开n次根的最小整数
read(n);
For(i,1,n) read(a[i]);
for(int i = 2, j = 1; i <= n+1; ++i)
if( a[i] == a[i-1] ) ++j;
else ans = max(ans,j), j = 1; // 特判q=1
for(int i = 1; i < n; ++i) {
vis.clear(); // 记录这个数字是否出现过
LL mn = min(a[i],a[i+1]), mx = max(a[i],a[i+1]);
if( mn == mx || mx % mn ) continue;
vis[mn] = vis[mx] = 1;
LL q = minq[mx/mn];
ans = max(ans,2);
for(int j = i+2; j <= n; ++j) {
if( vis[a[j]] ) break; // 公比不为1的等比数列中不能有相同的数字
vis[a[j]] = 1;
mn = min(a[j],a[j-1]), mx = max(a[j],a[j-1]);
if( mx % mn || minq[mx/mn] != q ) break;
ans = max(ans,j-i+1);
}
}
printf("%d\n",ans);
return 0;
}

熟练剖分(tree)

树形DP神题。发现如果直接DP的话祖先节点对重儿子的选择会影响子树的最长轻链长,于是考虑固定子树最长轻链长来计算出现的概率。

设 \(f[u,i]\) 为 \(u\) 的子树中到 \(u\) 的最长轻链长 \(i\) 的概率,答案为 \(\sum_{i=0}^ni\times f[rt,i]\)(长度乘概率)

第一维枚举重儿子 \(son\),第二维枚举儿子 \(v\),第三维枚举轻链长,这样可以通过子树的长度来推 \(u\) 的。考虑转移:设 \(g[k]\) 为 \(u\) 前面儿子中到 \(u\) 轻链长为 \(k\) 的概率,分类讨论:

  • \(son=v\):

    • \(v\) 子树链长 \(k\):\(+f[v,k]\times\sum_{i=1}^kg[k]\)(\(v\) 长 \(k\),其他不超过 \(k\))
    • 其他子树链长 \(k\):\(+g[k]\times\sum_{i=1}^kf[v,k]\)
    • 两部分都为 \(k\) 时有重复:\(-f[v,k]\times g[k]\)
  • \(son\neq v\):类似。只是注意此时 \((u,v)\) 为轻边,到 \(u\) 为 \(k\) 时到 \(v\) 为 \(k-1\)

实现:发现 \(\sum\) 会增加时间复杂度,因此对 \(f[u],g\) 作前缀和,注意在调用单点值时还原。

时间复杂度 \(O(n^2)\)(证明类似树形背包)

code
const int N = 3e3+5, p = 1e9+7;
int n;
vector<int> to[N]; int rt,fa[N],siz[N];
LL ans,f[N][N],g[N],h[N]; LL Pow(LL x,LL y)
{ LL res=1; for(;y;y>>=1,x=x*x%p)if(y&1)res=res*x%p; return res; } void dfs(int u) {
siz[u] = 1;
for(int v : to[u])
dfs(v), siz[u] += siz[v];
int tot = Pow(to[u].size(),p-2);
for(int son : to[u]) {
For(j,0,n) g[j] = 1;
for(int v : to[u]) {
For(k,0,siz[v]+1) {
// 计算g[k]时要用g[k-2..k],不能直接覆盖,要用h先存下来
LL gk = g[k]; // g[k]单点值d
if( k ) gk -= g[k-1];
if( son == v ) {
LL fk = f[v][k];// f[v][k]单点值
if( k ) fk -= f[v][k-1];
h[k] = (fk*g[k]%p + f[v][k]*gk%p - fk*gk%p +p)%p;
} else {
LL fk1 = f[v][k-1]; // f[v][k-1]单点值
if( k > 1 ) fk1 -= f[v][k-2];
h[k] = (fk1*g[k]%p + f[v][k-1]*gk%p - fk1*gk%p +p)%p;
// u-v为轻边,到u为k即到v为k-1
}
}
g[0] = h[0], h[0] = 0;
For(k,1,siz[v]+1) g[k] = (g[k-1] + h[k]) %p, h[k] = 0;
// h[k]为=k的概率, g[k]为<=k的
}
for(int j = siz[u]; j; --j) g[j] = (g[j] - g[j-1] +p) %p;
For(j,0,siz[u]) f[u][j] = (f[u][j] + g[j] * tot) %p;
}
if( !to[u].size() ) f[u][0] = 1;
For(i,1,siz[u]+1) f[u][i] = (f[u][i] + f[u][i-1]) %p; // f[u][i]为<=i的
} int main() {
read(n);
For(i,1,n) {
int son; read(son);
For(j,1,son) {
int x; read(x);
to[i].PB(x), fa[x] = i;
}
}
For(i,1,n) if( !fa[i] ) { rt = i; break; }
dfs(rt);
For(i,1,n) ans = (ans + i * (f[rt][i]-f[rt][i-1]+p)%p)%p;
printf("%lld",ans);
return 0;
}

建造游乐园(play)

首先要知道一些性质:

无向图度数为奇数的点有偶数个

欧拉图(有欧拉回路的图)中所有点的度数均为偶数

本题只给定点数,考虑从 \(1..i-1\) 个点推到 \(i\) 个点。设 \(f_i\) 为 \(i\) 个点的答案,\(g_i\) 为 \(i\) 个点不考虑连通性的答案,转移:

\[g_i=2^{\binom {i-1}2}
\]
\[f_i=g_i-\sum_{j=1}^{i-1}f_j\times g_{i-j}\times\binom{i-1}{j-1}
\]

解释:

\(g_i\):先用 \(i-1\) 个点随便连边,对于其中度数为奇数的再和剩下的 \(1\) 个点连边。

\(f_i\):在 \(g_i\) 的基础上减掉不连通的情况。

枚举点 \(1\) 所在连通块的大小 \(j\),则不用管剩下的 \(i-j\) 个点连不连通(因为这两部分一定不连通)

由于图有编号,而 \(f_j\) 只能统计出第一部分编号为 \(1..j\) 的,于是考虑用组合数算出编号的轮换。由于点 \(1\) 固定,因此组合数上下都 \(-1\)

时间复杂度 \(O(n^2)\)。

事实上,本题的式子类似 城市规划,只是不考虑联通性的答案 \(g_i\) 不同。因此理论上可以用fft做到 \(O(n\log n)\)

code
const int N = 2e3+5, p = 1e9+7;
int n; LL C[N][N],f[N],g[N]; LL Pow(LL x,LL y)
{ LL res=1; for(;y;y>>=1,x=x*x%p)if(y&1)res=res*x%p; return res; } int main() {
read(n);
For(i,0,n) {
C[i][0] = 1;
For(j,1,i) C[i][j] = (C[i-1][j-1] + C[i-1][j]) %p;
}
For(i,1,n) {
f[i] = g[i] = Pow(2,C[i-1][2]);
for(int j = 1; j < i; ++j)
f[i] = (f[i] - f[j] * g[i-j] %p * C[i-1][j-1] %p +p)%p;
}
printf("%lld",f[n]*C[n][2]%p);
return 0;
}

20210501 序列,熟练剖分(tree),建造游乐园(play)的更多相关文章

  1. 熟练剖分(tree) 树形DP

    熟练剖分(tree) 树形DP 题目描述 题目传送门 分析 我们设\(f[i][j]\)为以\(i\)为根节点的子树中最坏时间复杂度小于等于\(j\)的概率 设\(g[i][j]\)为当前扫到的以\( ...

  2. NOIP模拟测试3「序列·熟练剖分·建造游乐园(play)」

    ---恢复内容开始--- 序列 刚调出来样例就A了,假装是水题. 因为是乱序,我们要求出来每两项之间最小公比,而不是直接比 求出来每两项之间最小公比,然后扫一遍就完了.(还要注意重复情况) 那么问题就 ...

  3. HZOI2019熟练剖分(tree)

    题目大意:https://www.cnblogs.com/Juve/articles/11186805.html 题解: 先给出官方题解: 其实这题跟期望没什么关系,因为E=$\sum_\limits ...

  4. 【模拟7.14】B. 熟练剖分(tree) (概率DP)

    一道概率神题,考试时没读清题考完看了学长的玄学题解看了好几个小时 首先f[i][j]表示在点 i 为根的子树中,向下最长轻链长度小于等于 j 的概率. 首先递归下去并求出子树大小,然后枚举重儿子,枚举 ...

  5. 模拟3题解 T3建造游乐园

    T3建造游乐园 这题的关键是推式子 i个点中,有g[i]个方案是度为偶数但不一定连通那么就要减去不合法的设已有j个合法,其个数为f[j],剩下i-j个的方案数是g[i-j]选出来一个固定的点在合法的j ...

  6. BZOJ 2758 Blinker的噩梦(扫描线+熟练剖分+树状数组)

    题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2758 题意:平面上有n个多边形(凸包和圆).任意两个多边形AB只有两种关系:(1) ...

  7. BZOJ 3672 [Noi2014]购票 (熟练剖分+凸壳维护)

    题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3672 题意:给出一棵有根树(1为根),边有长度.每个点u有三个属性(len[u], ...

  8. [NOIP模拟测试3] 建造游乐园 题解(欧拉图性质)

    Orz 出题人石二队爷 我们可以先求出有n个点的联通欧拉图数量,然后使它删或增一条边得到我们要求的方案 也就是让它乘上$C_n^2$ (n个点里选2个点,要么删边要么连边,选择唯一) 那么接下来就是求 ...

  9. HZOI2019建造游乐园(play)组合数学,欧拉图

    题目:https://www.cnblogs.com/Juve/articles/11186805.html(密码是我的一个oj用户名) solution: 反正我是想不出来... 题目大意就是要求出 ...

随机推荐

  1. 2020国防科大综述:3D点云深度学习——综述(3D点云分割部分)

    目录 摘要 1.引言: 2.背景 2.1 数据集 2.2评价指标 3.3D点云分割 3.1 3D语义分割 3.1.1 基于投影的方法 多视图表示 球形表示 3.1.2 基于离散的方法 稠密离散表示 稀 ...

  2. alpakka-kafka(6)-kafka应用案例,用户接口

    了解了kafka原理之后,对kafka的的应用场景有了一些想法.在下面的一系列讨论中把最近一个项目中关于kafka的应用介绍一下. 先介绍一下使用kafka的起因:任何进销存系统,销售开单部分都应该算 ...

  3. Cell Reports | 上海瑞金医院糜坚青等揭示组蛋白酰化/乙酰化修饰比率调控BRD4基因组分布

    ​ 景杰生物 | 报道 组蛋白翻译后修饰,被认为构成一类超越基因序列的"组蛋白密码",控制着遗传信息的组织层次及其在染色质层面的解读.组蛋白赖氨酸乙酰化是研究最早的一类组蛋白修饰, ...

  4. 接口管理效率神器Apifox

    前言 你是一个测试,你们团队目前开发模式是前后端分离. 某一天,版本V1.0接口评审完,发布在了swagger上,前后端各自进行开发.此时你根据接口文档将新接口迁移到JMeter上,然后开始编写接口测 ...

  5. finalize() 方法——Java中垃圾回收提醒方法

    finalize() Java 允许定义这样的方法,它在对象被垃圾收集器析构(回收)之前调用,这个方法叫做 finalize( ),它用来清除回收对象. 例如,你可以使用 finalize() 来确保 ...

  6. Vue实现多文件上传功能(前端 + 后端代码)

    本人业余前端开发,因为公司(很坑)觉得我很牛逼,所以让我前后端一起玩,无奈的我只能磕磕碰碰的研究起了vue. 开发项目的时候,用到文件上传的功能很常见,包括单文件上传和多文件上传,上传各种类型的文件. ...

  7. 记一次在Windows10桌面环境搭建Jekins的吐血经历

    目录 写在前面 故事背景 踩坑详情 最后总结 写在前面 首先声明,除非万不得已,千万不要在Windows环境做这个事情,否则就等着各种坑吧. 本人一贯的立场都是坚持用正确的方法做事,显然在Window ...

  8. Linux进程间通信方式--信号,管道,消息队列,信号量,共享内存

    1.概述 通信方法 无法介于内核态与用户态的原因 管道(不包括命名管道) 局限于父子进程间的通信. 消息队列 在硬.软中断中无法无阻塞地接收数据. 信号量 无法介于内核态和用户态使用. 内存共享 需要 ...

  9. CD管理和检索软件比较

    之前一直用EverCD+,考虑到鸡蛋不能放在一个篮子里,又找了几款功能类似的进行了比较,主要考察一下几个功能: 多个镜像:一个数据文件可以包含多个目录的镜像,便于数据管理和搜索: 目录更新:目录内容发 ...

  10. iOS-block循环引用详解和应用

    Block循环引用 什么情况下block会造成循环引用 ARC 情况下 block为了保证代码块内部对象不被提前释放,会对block中的对象进行强引用,就相当于持有了其中的对象,而如果此时block中 ...