标签:begin -- style 后缀 log main 最大的 highlight ati
题面原文大致如下:
有n个单词,从小到大填入表,对于序号为x的单词(1~x-1都已被填入):
求最小代价。
写题面的人脑子打了结吧能写出这种见鬼的描述,逻辑被狗吃了。
第二个条件相当于说:当它的所有后缀都被填入表内的情况下,表内的单词都不是它的后缀。
这句子是人写出来的吗。
然后你必须推导出这句话的意思是:“它的所有后缀”为空集。
而“它的所有后缀”是指是它的后缀的所有单词。
最后把这个题面翻译成人话就是:
然后就是个sb贪心。
我还能说什么呢。
只有我一个人读不懂题吗,真是惨无人道。
#include<bits/stdc++.h>
#define S t[u][z[j]-97]
#define I t[u][i]
#define pb push_back
#define RAN(v)v.begin(),v.end()
#define FOR(i,v) for(typeof(v.end())i=v.begin();i!=v.end();++i)
using namespace std;
typedef long long ll;
const int N=100005;
const int M=510005;
int n,tot;
char z[M];
int t[M][26],l[M],r[N];
ll f[N];
vector<int>e[N];
bool foo(int i,int j){
return r[i]<r[j];
}
void dfs1(int u,int v){
if(l[u])e[v].pb(l[u]);
for(int i=0;i<26;++i)
if(I)dfs1(I,l[u]?l[u]:v);
}
void dfs2(int u){
r[u]=1;
FOR(i,e[u])
dfs2(*i),r[u]+=r[*i];
sort(RAN(e[u]),foo);
f[u]=1;
int s=0;
FOR(i,e[u])
f[u]+=f[*i]+s,s+=r[*i];
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;++i){
scanf("%s",z);
int u=0;
for(int j=strlen(z)-1;~j;--j)
u=S?S:S=++tot;
l[u]=i;
}
dfs1(0,0),dfs2(0);
printf("%lld\n",f[0]-1);
}
标签:begin -- style 后缀 log main 最大的 highlight ati
原文地址:http://www.cnblogs.com/f321dd/p/6600264.html