zoukankan      html  css  js  c++  java
  • BZOJ4567: [Scoi2016]背单词

    题面原文大致如下:

    有n个单词,从小到大填入表,对于序号为x的单词(1~x-1都已被填入):

    1. 如果存在一个单词是它的后缀,并且当前没有被填入表内,代价为n*n;
    2. 当它的所有后缀都被填入表内的情况下,如果在1~x-1的位置上的单词都不是它的后缀,代价为x;
    3. 当它的所有后缀都被填入表内的情况下,如果1~x-1的位置上存在是它后缀的单词,所有是它后缀的单词中,序号最大为y,代价为x-y。

    求最小代价。

    写题面的人脑子打了结吧能写出这种见鬼的描述,逻辑被狗吃了。

    第二个条件相当于说:当它的所有后缀都被填入表内的情况下,表内的单词都不是它的后缀。

    这句子是人写出来的吗。

    然后你必须推导出这句话的意思是:“它的所有后缀”为空集。

    而“它的所有后缀”是指是它的后缀的所有单词。

    最后把这个题面翻译成人话就是:

    1. 如果存在一个单词是它的后缀,且当前没被填入,代价为n*n;
    2. 如果不存在一个单词是它的后缀,代价为x;
    3. 如果存在一个单词是它的后缀,且已填入的是它后缀的单词中序号最大的为y,代价为x-y。

    然后就是个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
    ",f[0]-1);
    }
    
  • 相关阅读:
    Web后门工具WeBaCoo
    苹果内存取证工具volafox
    PlayMaker GUI的Normalized
    Arduino可穿戴教程之第一个程序——选择端口(三)
    缩略图信息提取工具vinetto
    jquery的defer
    toDo
    瀑布流案例
    js基本知识6
    js基本知识5
  • 原文地址:https://www.cnblogs.com/f321dd/p/6600264.html
Copyright © 2011-2022 走看看