2018ECfinal J. Philosophical Balance

题目大意:

给出一个字符串 \(s\) ,你需要给每一个 \(i\) 一个 \([0,1]\) 之间的权值 \(k_i\) ,且满足 \(\sum k_i=1\) 。并且最小化

\[\max_{i=1}^n(\sum_{j=1}^nlcp(suf(s,j),suf(s,i))\times k_j)
\]

先证明一个比较简单的结论,把 \(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\) 到父亲的边直接加上去就可以。然后剩下的东西是一个纳什均衡的模型,可以当做博弈来理解,最优解的一定是每个儿子的贡献相等,乱推一波可以得到式子:

\[\sum {k_i} = 1 \\
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的更多相关文章

  1. 【做题】ECFinal2018 J - Philosophical … Balance——dp

    原文链接 https://www.cnblogs.com/cly-none/p/ECFINAL2018J.html 题意:给出一个长度为\(n\)的字符串\(s\),要求给\(s\)的每个后缀\(s[ ...

  2. 2018 EC-Final 部分题解 (A,J)

    目录 The 2018 ICPC Asia-East Continent Final A.Exotic - Ancient City(思路 并查集) J.Philosophical - Balance ...

  3. POJ 1013 Counterfeit Dollar

    Counterfeit Dollar Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 36206   Accepted: 11 ...

  4. asp.net使用MVC4框架基于NPOI做导出数据到Excel表

    NPOI 是 POI 项目的 .NET 版本.POI是一个开源的Java读写Excel.WORD等微软OLE2组件文档的项目. 使用 NPOI 你就可以在没有安装 Office 或者相应环境的机器上对 ...

  5. POJ 1013 Counterfeit Dollar 集合上的位运算

    Description Sally Jones has a dozen Voyageur silver dollars. However, only eleven of the coins are t ...

  6. poj1837挂砝码

    解法(背包DP问题) (下为转) 其实感觉 像此题这种类型的并不属于dp范畴 虽然程序看起来使用的是递推这一过程,但总不能说开个二重循环就是dp吧 如果只从求解上来讲(不考虑数据值的范围), 只有枚举 ...

  7. LB(Load balance)负载均衡集群--{LVS-[NAT+DR]单实例实验+LVS+keeplived实验} 菜鸟入门级

    LB(Load balance)负载均衡集群 LVS-[NAT+DR]单实例实验 LVS+keeplived实验 LVS是Linux Virtual Server的简写,意即Linux虚拟服务器,是一 ...

  8. POJ1837 Balance[分组背包]

    Balance Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 13717   Accepted: 8616 Descript ...

  9. Codeforces Beta Round #17 C. Balance DP

    C. Balance 题目链接 http://codeforces.com/contest/17/problem/C 题面 Nick likes strings very much, he likes ...

随机推荐

  1. Configure Always On Availability Group for SQL Server on Ubuntu——Ubuntu上配置SQL Server Always On Availability Group

    下面简单介绍一下如何在Ubuntu上一步一步创建一个SQL Server AG(Always On Availability Group),以及配置过程中遇到的坑的填充方法. 目前在Linux上可以搭 ...

  2. 通过cordova将vue项目打包为webapp

    准备工作:需要之前配置好vue-cli脚架构,安装好cordova环境.下面开始对vue.js项目进行打包,打包环境为Android. 可以看下我的github:https://github.com/ ...

  3. AJAX的前世今生与未来

    一.通过三个问答来认识一下Ajax 什么是Ajax? Ajax是Asynchronous Javascript And XML的缩写,它是一种技术. Ajax有什么用? 这一技术能够向服务器请求额外的 ...

  4. 去除IE10+上文本框巨丑无比的删除图标以及显示密码图标

    去除IE10+上文本框巨丑无比的删除图标以及显示密码图标 IE浏览器总是让人喜欢让人厌,在最新的IE浏览器(IE10+)上使用表单时,文本框内后面会出现很巨丑无比的“删除图标”以及“显示密码图标”,如 ...

  5. python实战===python程序打包成exe

    推荐PyInstaller项目www.pyinstaller.org   安装方法: 先跑pip install pywin32再跑pip install pyinstaller即可 可用一句命令打包 ...

  6. 安装ssh-keygen

    转载自:http://www.daoan.com/forums/index.php?forumid=5&mods=topicdisplay&postid=4 sudo apt-get ...

  7. 191.Number of 1Bits---位运算---《剑指offer》10

    题目链接:https://leetcode.com/problems/number-of-1-bits/description/ 题目大意:与338题类似,求解某个无符号32位整数的二进制表示的1的个 ...

  8. Python抓取微博评论(二)

    对于新浪微博评论的抓取,首篇做的时候有些考虑不周,然后现在改正了一些地方,因为有人问,抓取评论的时候“爬前50页的热评,或者最新评论里的前100页“,这样的数据看了看,好像每条微博的评论都只能抓取到前 ...

  9. es 插件

    类 若 实现NativeScriptFactory接口.A factory to create instances of either {@link ExecutableScript} or {@li ...

  10. laravel5.1--数据库操作

    1 配置信息 1.1配置目录: config/database.php 1.2配置多个数据库 //默认的数据库 'mysql' => [ 'driver' => 'mysql', 'hos ...