2018ECfinal J. Philosophical Balance
2018ECfinal J. Philosophical Balance
题目大意:
给出一个字符串 \(s\) ,你需要给每一个 \(i\) 一个 \([0,1]\) 之间的权值 \(k_i\) ,且满足 \(\sum k_i=1\) 。并且最小化
\]
先证明一个比较简单的结论,把 \(s\) 的后缀树建出来,考虑后缀树的每一个子树,如果子树的根是 \(s\) 的一个后缀,那么分配到这个子树里面的所有权值必然全部分配到根上。
假设这个子树 \(u\) 里第 \(i\) 个节点分配了 \(k_i\) 的权值,那么对于根的贡献是 \(\sum{k_i}\times len_{u}\) ,考虑对其它点的贡献是每一个权值乘在其某个祖先的 \(len\) 上,由于 \(len\) 向上递减,根的贡献固定,那么显然全部放在根上最优。
设 \(f(u)\) 为后缀树上 \(u\) 节点所在子树内部的答案,当 \(u\) 是后缀节点的时候 \(f(u)=len(fa_u)-len(u)\) 。否则只需要合并每一个儿子的 \(f(v)\) 。
考虑儿子与儿子之间是独立的,不同儿子之间的 \(lcp\) 都是 \(u\) ,也就是说 \(u\) 代表的串无论 \(i\) 是什么都会被算 \(\sum k_i=1\) 的系数。那么 \(u\) 到父亲的边直接加上去就可以。然后剩下的东西是一个纳什均衡的模型,可以当做博弈来理解,最优解的一定是每个儿子的贡献相等,乱推一波可以得到式子:
f_1k_1 = f_2k_2=\dots= f_mk_m= x \\
\sum \frac{x}{f_i}=1 \\
\frac{1}{x} = \sum \frac{1}{f_i} \\
x = \frac{1}{\sum \frac{1}{f_i}}
\]
其实上面那个证明带进去发现当根节点是后缀节点的时候贡献是相等的,打表一下应该不难看出这个后面那个结论了,之后 \(\mathcal O(n)\) 算一算就做完了。
/*program by mangoyang*/
#pragma GCC optimize("Ofast", "inline")
#include <bits/stdc++.h>
#define inf (0x7f7f7f7f)
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
typedef long long ll;
using namespace std;
template <class T>
inline void read(T &x){
int ch = 0, f = 0; x = 0;
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
if(f) x = -x;
}
#define double long double
const int N = 500005;
vector<int> vec[N];
char s[N];
ll all, val[N]; int n, cnt;
namespace SAM{
vector<int> g[N];
int ch[N][26], pos[N], fa[N], len[N], size = 1, tail = 1;
inline int newnode(int x){ return len[++size] = x, size; }
inline void ins(int c, int x){
int p = tail, np = newnode(len[p] + 1); pos[np] = x;
for(; p && !ch[p][c]; p = fa[p]) ch[p][c] = np;
if(!p) return (void) (fa[np] = 1, tail = np);
int q = ch[p][c];
if(len[q] == len[p] + 1) fa[np] = q;
else{
int nq = newnode(len[p] + 1);
fa[nq] = fa[q], fa[q] = fa[np] = nq;
for(int i = 0; i < 26; i++) ch[nq][i] = ch[q][i];
for(; p && ch[p][c] == q; p = fa[p]) ch[p][c] = nq;
}tail = np;
}
inline void addedge(){
for(int i = 2; i <= size; i++) g[fa[i]].push_back(i);
}
inline double gao(int u, int d){
if(pos[u]) return d;
double res = 0;
for(int i = 0; i < (int) g[u].size(); i++)
res += 1.0 / gao(g[u][i], len[g[u][i]] - len[u]);
return 1.0 / res + d;
}
}
int main(){
int T; read(T);
while(T--){
for(int i = 1; i <= SAM::size; i++){
SAM::g[i].clear();
SAM::pos[i] = SAM::fa[i] = SAM::len[i] = 0;
memset(SAM::ch[i], 0, sizeof(SAM::ch[i]));
}
SAM::tail = SAM::size = 1;
scanf("%s", s + 1); n = strlen(s + 1);
for(int i = n; i; i--) SAM::ins(s[i] - 'a', i);
SAM::addedge();
printf("%.10Lf\n", SAM::gao(1, 0));
}
}
2018ECfinal J. Philosophical Balance的更多相关文章
- 【做题】ECFinal2018 J - Philosophical … Balance——dp
原文链接 https://www.cnblogs.com/cly-none/p/ECFINAL2018J.html 题意:给出一个长度为\(n\)的字符串\(s\),要求给\(s\)的每个后缀\(s[ ...
- 2018 EC-Final 部分题解 (A,J)
目录 The 2018 ICPC Asia-East Continent Final A.Exotic - Ancient City(思路 并查集) J.Philosophical - Balance ...
- POJ 1013 Counterfeit Dollar
Counterfeit Dollar Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 36206 Accepted: 11 ...
- asp.net使用MVC4框架基于NPOI做导出数据到Excel表
NPOI 是 POI 项目的 .NET 版本.POI是一个开源的Java读写Excel.WORD等微软OLE2组件文档的项目. 使用 NPOI 你就可以在没有安装 Office 或者相应环境的机器上对 ...
- POJ 1013 Counterfeit Dollar 集合上的位运算
Description Sally Jones has a dozen Voyageur silver dollars. However, only eleven of the coins are t ...
- poj1837挂砝码
解法(背包DP问题) (下为转) 其实感觉 像此题这种类型的并不属于dp范畴 虽然程序看起来使用的是递推这一过程,但总不能说开个二重循环就是dp吧 如果只从求解上来讲(不考虑数据值的范围), 只有枚举 ...
- LB(Load balance)负载均衡集群--{LVS-[NAT+DR]单实例实验+LVS+keeplived实验} 菜鸟入门级
LB(Load balance)负载均衡集群 LVS-[NAT+DR]单实例实验 LVS+keeplived实验 LVS是Linux Virtual Server的简写,意即Linux虚拟服务器,是一 ...
- POJ1837 Balance[分组背包]
Balance Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 13717 Accepted: 8616 Descript ...
- Codeforces Beta Round #17 C. Balance DP
C. Balance 题目链接 http://codeforces.com/contest/17/problem/C 题面 Nick likes strings very much, he likes ...
随机推荐
- 【CF343D】 Water Tree(树链剖分)
题目链接 树剖傻逼题,练练手好久没写树剖了. 查询忘记\(pushdown\)抓了好久虫.. 全文手写,一遍过... #include <cstdio> const int MAXN = ...
- NYOJ 756 重建二叉树 (二叉树)
题目链接 描述 题目很简单,给你一棵二叉树的后序和中序序列,求出它的前序序列(So easy!). 输入 输入有多组数据(少于100组),以文件结尾结束.每组数据仅一行,包括两个字符串,中间用空格隔开 ...
- Sublime之快捷键(二)
1. 在使用Sublime的时候,经常用到选中文件中相同的一些字段,那怎么办呢? 快捷键: ctrl + d 可以快速的选择,你所选中的文字,每次按下该快捷键,就会自动的寻找相同的字段: Alt + ...
- 安装node-sass的正确姿势【转】
安装 node-sass 的时候总是会各种不成功,今天我琢磨了一会儿总算知道要怎么解决了. 首先要知道的是,安装 node-sass 时在 node scripts/install 阶段会从 gith ...
- 工具===激活xmind 8
[下载jar包]: https://stormxing.oss-cn-beijing.aliyuncs.com/files/XMindCrack.jar 方法: 打开xmind 8 安装目录的 ...
- 大数据系列之Flume+kafka 整合
相关文章: 大数据系列之Kafka安装 大数据系列之Flume--几种不同的Sources 大数据系列之Flume+HDFS 关于Flume 的 一些核心概念: 组件名称 功能介绍 Agent ...
- WPF之换肤
WPF之换肤 设计原理 WPF换肤的设计原理,利用资源字典为每种皮肤资源添加不同的样式,在后台切换皮肤资源文件. 截图 上图中,第一张图采用规则样式,第二张图采用不规则样式,截图的时候略有瑕疵. 资源 ...
- 中文chrome font-size 10px,11px,12px,rem只为12px解决办法
问题来源: html { font-size: 10px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); } .form-signin { max-wi ...
- cvc-complex-type.2.4.a: Invalid content was found starting with element ‘init-param’(转)
在写xml的时候又一次总是报cvc-complex-type.2.4.a: Invalid content was found starting with element 错误,还出现小红叉,在网上找 ...
- C# 中DateTime的各种使用
获得当前系统时间: DateTime dt = DateTime.Now; Environment.TickCount可以得到“系统启动到现在”的毫秒值 DateTime now = DateTime ...