试题描述 |
Lweb 面对如山的英语单词,陷入了深深的沉思,「我怎么样才能快点学完,然后去玩三国杀呢?」。这时候睿智的凤老师从远处飘来,他送给了 Lweb 一本计划册和一大缸泡椒,然后凤老师告诉 Lweb ,我知道你要学习的单词总共有 n个,现在我们从上往下完成计划表,对于一个序号为 x 的单词(序号 1…x−1 都已经被填入): 如果存在一个单词是它的后缀,并且当前没有被填入表内,那他需要吃 n×n颗泡椒才能学会; 当它的所有后缀都被填入表内的情况下,如果在 1…x−1的位置上的单词都不是它的后缀,那么你吃 x 颗泡椒就能记住它; 当它的所有后缀都被填入表内的情况下,如果 1…x−1 的位置上存在是它后缀的单词,所有是它后缀的单词中,序号最大为 y ,那么你只要吃 x−y 颗泡椒就能把它记住。 Lweb 是一个吃到辣辣的东西会暴走的奇怪小朋友,所以请你帮助 Lweb,寻找一种最优的填写单词方案,使得他记住这 n 个单词的情况下,吃最少的泡椒。 |
输入 |
输入一个整数 n ,表示 Lweb 要学习的单词数。接下来 n 行,每行有一个单词(由小写字母构成,且保证任意单词两两互不相同,1≤n≤100000 ,所有字符的长度总和 1≤∣len∣≤510000 ) |
输出 |
Lweb 吃的最少泡椒数。 |
输入示例 |
2aba |
输出示例 |
2 |
其他说明 |
数据范围与提示 1≤n≤100000 ,所有字符的长度总和 1≤∣len∣≤510000 |
这道题考什么呢?
是读题啦!
写了两天的代码,发现结果错误,然后看题解,发现我理解错了
我这人平时是很温和的,也不轻易D人,然而这次有点忍不了
这TM是什么JB玩意儿,出题人教你语文的体育老师还健在吗
别的题解D的都比我好,大家有兴趣就可以去看
首先是trie树无疑了,但是我们发现只与后缀有关
所以要反向存
然后就是一波贪心
然后就是这题最好别做
还有就是要卡int
下面给出代码:
#include#include #include #include #include #include #include using namespace std;inline long long rd(){ long long x=0,f=1; char ch=getchar(); for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1; for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0'; return x*f;}inline void write(long long x){ if(x<0) putchar('-'),x=-x; if(x>9) write(x/10); putchar(x%10+'0'); return ;}long long n;long long trie[510006][50];long long total=1;long long len;long long vis[510006];long long head[510006],nxt[510006],to[510006];long long tot=0;void add(long long x,long long y){ tot++; to[tot]=y; nxt[tot]=head[x]; head[x]=tot; return ;}char x[510006];void pre(long long v){ long long c=1; for(long long i=len;i>=1;i--){ long long s=x[i]-'a'; if(!trie[c][s]) trie[c][s]=++total; c=trie[c][s]; } vis[c]=v; return ;}void dfs(long long x,long long y){ if(vis[x]) add(y,vis[x]),y=vis[x]; for(long long i=0;i<=30;i++) if(trie[x][i]) dfs(trie[x][i],y); return ;}struct node{ long long dis,v;}s[510006];long long num[510006];long long ans=0;bool cmp(node x,node y){ return x.dis