首页 > 其他分享 >[ABC264G] String Fair

[ABC264G] String Fair

时间:2023-01-07 15:55:39浏览次数:54  
标签:26 String Fair int void SON define ABC264G dis

[ABC264G] String Fair Solution

目录

更好的阅读体验戳此进入

题面

给定 $ n $ 条评分规则,每条存在字符串 $ T_i $ 和得分 $ P_i $。你需要构造一个任意长度但非空的字符串 $ S $,在 $ S $ 中每次出现 $ T_i $ 就会获得 $ P_i $ 得分。你需要最大化得分,输出最大值。若无限大则输出 Infinity

Solution

一个十分精妙的图论。

关键的信息在 $ \lvert T_i \rvert \le 3 $,这样的话我们就可以考虑进行建边。我们令 $ P_{str} $ 表示字符串为 $ str $ 的时候的得分,如果没有该字符串的评分规则即为 $ 0 $。

于是考虑如对于从 $ ab $ 通过 $ c $ 可以有一条边到 $ bc $,边权即为 $ P_{abc} + P_{bc} + P_{c} $。同时注意一些细节,如从空字符串可以通过任意字符,如通过 $ a $ 连结到 $ a $,边权即为 $ P_a $,以及对于长度为 $ 1 $ 的字符串连结到长度为 $ 2 $ 的同理。

这样将图建完之后不难发现只需要 SPFA 跑一遍单源最长路,取最大的 $ dis $ 即可,如果存在正环那么显然无限大。

于是点数为 $ n = 26^2 + 26 + 1 $,边数即为 $ m = 26n $,于是 SPFA 最坏复杂度即为 $ O(nm) $,也就是 $ 26^5 $ 的级别,可以通过。

当然这里我们用 map 实现,手动实现一个 hash() 之后用 unorderer_map 即可去掉 map 的 $ \log $。

Code

#define _USE_MATH_DEFINES
#include <bits/stdc++.h>

#define PI M_PI
#define E M_E
#define npt nullptr
#define SON i->to
#define OPNEW void* operator new(size_t)
#define ROPNEW(arr) void* Edge::operator new(size_t){static Edge* P = arr; return P++;}

using namespace std;

mt19937 rnd(random_device{}());
int rndd(int l, int r){return rnd() % (r - l + 1) + l;}
bool rnddd(int x){return rndd(1, 100) <= x;}

typedef unsigned int uint;
typedef unsigned long long unll;
typedef long long ll;
typedef long double ld;



template < typename T = int >
inline T read(void);

struct Edge{
    Edge* nxt;
    int to;
    ll val;
    OPNEW;
}ed[21000];
ROPNEW(ed);
Edge* head[1100];

int N;
int cnt(0);
unordered_map < string, int > score;
map < pair < int, int >, int > mp;
unordered_map < int, pair < int, int > > rmp;
bitset < 1100 > inq;
int dep[1100];
ll dis[1100];
ll ans(LONG_LONG_MIN);

void SPFA(void){
    memset(dis, 0xc0, sizeof dis);
    queue < int > cur;
    cur.push(1); inq[1] = true; dep[1] = 1, dis[1] = 0;
    while(!cur.empty()){
        int p = cur.front(); cur.pop();
        inq[p] = false;
        for(auto i = head[p]; i; i = i->nxt){
            if(dis[p] + i->val > dis[SON]){
                dis[SON] = dis[p] + i->val;
                ans = max(ans, dis[SON]);
                dep[SON] = dep[p] + 1;
                if(dep[SON] > 26 * 26 + 26 + 1)printf("Infinity\n"), exit(0);
                if(!inq[SON])cur.push(SON), inq[SON] = true;
            }
        }
    }
}

int main(){
    N = read();
    for(int i = 1; i <= N; ++i){
        string S; cin >> S;
        score.insert({S, read()});
    }mp.insert({{0, 0}, ++cnt}), rmp.insert({cnt, {0, 0}});
    for(int i = 'a'; i <= 'z'; ++i)mp.insert({{0, i}, ++cnt}), rmp.insert({cnt, {0, i}});
    for(int i = 'a'; i <= 'z'; ++i)for(int j = 'a'; j <= 'z'; ++j)
        mp.insert({{i, j}, ++cnt}), rmp.insert({cnt, {i, j}});
    for(int i = 1; i <= cnt; ++i)for(int j = 'a'; j <= 'z'; ++j){
        ll tot(0); string S;
        if(rmp[i].first)S += (char)rmp[i].first;
        if(rmp[i].second)S += (char)rmp[i].second;
        S += j; tot += score[S];
        while(!S.empty()){
            S.erase(S.begin());
            tot += score[S];
        }
        head[i] = new Edge{head[i], mp[{rmp[i].second, j}], tot};
    }SPFA();
    printf("%lld\n", ans);
    fprintf(stderr, "Time: %.6lf\n", (double)clock() / CLOCKS_PER_SEC);
    return 0;
}

template < typename T >
inline T read(void){
    T ret(0);
    int flag(1);
    char c = getchar();
    while(c != '-' && !isdigit(c))c = getchar();
    if(c == '-')flag = -1, c = getchar();
    while(isdigit(c)){
        ret *= 10;
        ret += int(c - '0');
        c = getchar();
    }
    ret *= flag;
    return ret;
}

UPD

update-2023_01_03 初稿

标签:26,String,Fair,int,void,SON,define,ABC264G,dis
From: https://www.cnblogs.com/tsawke/p/17032811.html

相关文章

  • StringCbCatW与StringCchCatW的区别
    仔细看官方文档里,区别主要在第二个参数:StringCchCatW的cbDest:以字节为单位StringCchCatW的cchDest:以字符为单位大家根据实际情况选择合适的函数。附:StringCbCat、Stri......
  • 认识 Java 中的 StringBuilder 类
    Stringstr="hello"; System.out.println(str); System.out.println(str+"world"); }输出的结果是:hellohelloworld从运行结果中我们可以看到,程序运行时会额外创建......
  • string容器拼接
    string字符串拼接1函数原型:2string&operator+=(constchat*str);//重载+=操作符号3string&operator+=(constcharc)//重载+=操作符4string&operator+=(......
  • Java中的StringUtils引入及使用
    pom.xml中引入依赖<!--https://mvnrepository.com/artifact/org.apache.commons/commons-lang3--><dependency><groupId>org.apache.commons</groupId><artifactId>......
  • String的intern()方法浅析
    intern()方法优点:执行速度非常快,直接使用==进行比较要比使用equals()方法快很多;内存占用少。虽然intern()方法的优点看上去很诱人,但由于intern()操作每次都需要与常量......
  • 字符串转化使用String.valueOf(value) 代替 “ “ + value
    文章目录把其它对象或类型转化为字符串时,使用String.valueOf(value)比“”+value的效率更高。//把其它对象或类型转化为字符串反例:intnum=520;//""+valueStringst......
  • Java String为什么被设计为final的
    文章目录String被设计为不可变是因为String对象是缓存在字符串池中的,因此这些缓存的字符串是可以被多个客户端访问的,如果一个客户端的访问影响了别的客户端的行为,这样就存在......
  • JavaScript: symbol 和 string key 取值时的怪异现象
    ''做key可以被.或者[]运算符取出[""]做key同样可以被.或者[]运算符取出symbol做key只能被.取出[symbol]做key只能被[]取出......
  • String 内存地址透析
    publicstaticvoidmain(String[]args){Stringa1=newString("1")+newString("1");a1.intern();Stringb1="11";System.......
  • 为什么Python中的re.compile()输入要用raw string(r'')?
    在re这一模块的官方文档的解释如下Regularexpressionsusethebackslashcharacter('')toindicatespecialformsortoallowspecialcharacterstobeusedwitho......