abc419
很久没写过这种东西了。
A
非常有必要说!但是不知道从哪里说。所以给个代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
    string str;cin >> str;
    if(str == "red")cout << "SSS";
    else if(str == "blue")cout << "FFF";
    else if(str == "green")cout << "MMM";
    else if(str == "yellow")cout << "RRR";
    else cout << "Unknown";
    return 0;
}
B
没必要说的。
C
卡了非常久。
给个式子:\(\max(\lceil \dfrac{maxx - minx}{2} \rceil,\lceil \dfrac{maxy - miny}{2} \rceil)\)。
D
发现操作即为将 \(l \sim r\) 的数反转。然后前缀和维护,做完了。但是怎么还罚了一发啊。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 5e5 + 10;
string S,T;
int n,m,c[maxn];
int main()
{
    cin >> n >> m >> S >> T;S = " " + S;T = " " + T;
    while(m--)
    {
        int l,r;cin >> l >> r;
        c[l] ^= 1;c[r + 1] ^= 1;
    }
    for(int i = 1;i <= n;i++)c[i] ^= c[i - 1];
    for(int i = 1;i <= n;i++)cout << (c[i] ? T[i] : S[i]);
    return 0;
}
E
脑电波。注意到 \(s_j \equiv s_{l+j} \pmod m\)。然后令 \(dp_{i,j}\) 表示所有 \(k\times l + i\) 的位置的数全部除 \(m\) 模 \(j\),然后随便转移。
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn = 510;
int n,m,l,ans,pos[maxn][maxn],dp[maxn][maxn];vector<int> vec[maxn];
int calc(int j,int u){return (u - j % m + m) % m;}
signed main()
{
    cin >> n >> m >> l;
    for(int i = 1;i <= n;i++)
    {
        int x;cin >> x;
        vec[i % l].push_back(x);
    }
    for(int i = 0;i < l;i++)for(int j = 0;j < m;j++)for(int u : vec[i])pos[i][j] += calc(u,j);
    memset(dp,63,sizeof(dp));dp[0][0] = 0;
    for(int i = 1;i <= l;i++)
    {
        for(int j = 0;j < m;j++)
        {
            for(int k = 0;k < m;k++)
            {
                dp[i][j] = min(dp[i][j],dp[i - 1][k] + pos[i % l][(j - k + m) % m]);
            }
        }
    }
    cout << dp[l][0];
    return 0;
}
F
唐的没边,但是更唐的是我。
定义 \(dp_{l,u,m}\) 表示长度为 \(l\) 的字符串,当前在自动机状态 \(u\),已经匹配的字符串集合为 \(m\) 的数量。
然后转移就是:
其中 \(v\) 为 \(u\) 经过字符 \(c\) 的转移得到的状态 \(v\),\(S_v\) 表示以 \(v\) 节点为结尾的字符串数量,结束。
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int mod = 998244353;
const int maxn = 1e5 + 10;
namespace ACAM
{
    int tr[maxn][30],fail[maxn],tot;
    char s[maxn];int nodeS[maxn];
    void insert(int id)
    {
        cin >> s + 1;int u = 0;
        for(int i = 1;s[i];i++)
        {
            if(!tr[u][s[i] - 'a']) tr[u][s[i] - 'a'] = ++tot;
            u = tr[u][s[i] - 'a'];
        }
        nodeS[u] |= (1 << id);
    }
    queue<int> q;
    void build()
    {
        for(int i = 0;i < 26;i++)if(tr[0][i])q.push(tr[0][i]);
        while(q.size())
        {
            int u = q.front();q.pop();
            for(int i = 0;i < 26;i++)
            {
                if(tr[u][i])fail[tr[u][i]] = tr[fail[u]][i],q.push(tr[u][i]);
                else tr[u][i] = tr[fail[u]][i];
                nodeS[tr[u][i]] |= nodeS[fail[tr[u][i]]];
            }
        }
    }
}using namespace ACAM;
int dp[105][105][500];
signed main()
{
    int n,L;cin >> n >> L;
    for(int i = 0;i < n;i++)insert(i);
    build();dp[0][0][0] = 1;
    for(int l = 0;l < L;l++)
    {
        for(int u = 0;u <= tot;u++)
        {
            for(int S = 0;S < 1 << n;S++)
            {
                if(!dp[l][u][S])continue;
                for(int i = 0;i < 26;i++)
                {
                    int v = u;
                    while(v && !tr[v][i])v = fail[v];
                    int nS = S | nodeS[tr[v][i]];
                    dp[l + 1][tr[v][i]][nS] = (dp[l + 1][tr[v][i]][nS] + dp[l][u][S]) % mod;
                }
            }
        }
    }
    int ans = 0;
    for(int i = 0;i <= tot;i++)ans = (ans + dp[L][i][(1 << n) - 1]) % mod;
    cout << ans;
    return 0;
}
G
唐的没边,但是更唐的是我。
\(\text{Sol 1}\)
先找出一颗 DFS 树,那么这棵树上会对于答案会有贡献的就是这棵树上的后向边。
然后考虑把所有的后向边的两个端点拉出来,建一颗虚树。此时你发现这个虚树的点数是 \(2k\) 的,其中 \(k = m - n + 1\)。那么你可以直接用 \(\mathrm O(k2^k)\) 去暴力枚举整一颗树,然后去计算所有的路径。
code。
\(\text{Sol 2}\)
注意到 \(m - n \le 20\),所以考虑使用广义串并连通图方法来做这个题。
广义串并连通图方法对于图长什么样没有任何限制。
接下来考虑进行以下几种操作:
- 删一度点:选择一个度数为 \(1\) 的点并删掉它和与它连接的边。
 - 缩二度点:选择一个度数为 \(2\) 的点,用一条边替换它和与它相连的两条边。
 - 叠重边:选择两条重边,用一条边替换它们。
 
做完以上的操作之后,我们知道一定只剩度数 \(\ge 3\) 的点了,所以 \(3n \le 2m\)。那么我们就有 \(n \le 2k,m \le 3k\)。
那么接下来的操作就和 \(\text{Sol 1}\) 后面的操作一样了。
code。

                
            
        
浙公网安备 33010602011771号