AtCoder Grand Contest 020 (AGC020) E - Encoding Subsets 动态规划

原文链接www.cnblogs.com/zhouzhendong/p/AGC020E.html

前言

真 \(\cdot\) 信仰型动态规划

题解

我们可以采用信仰型动态规划解决此题。

设 \(dp[S]\) 表示 S 这个字符串的所有子集可以被编码成多少种。

那么分两种情况转移:

  1. 不编码,答案是子集总数。
  2. 考虑枚举最左边的一处编码,递归DP。

时间复杂度 \(O(信仰)\) 。

时间复杂度证明?详见官方题解。反正我没去看。

代码

#include <bits/stdc++.h>
#define clr(x) memset(x,0,sizeof x)
#define For(i,a,b) for (int i=(a);i<=(b);i++)
#define Fod(i,b,a) for (int i=(b);i>=(a);i--)
#define fi first
#define se second
#define pb(x) push_back(x)
#define mp(x,y) make_pair(x,y)
#define outval(x) cerr<<#x" = "<<x<<endl
#define outtag(x) cerr<<"---------------"#x"---------------"<<endl
#define outarr(a,L,R) cerr<<#a"["<<L<<".."<<R<<"] = ";                        For(_x,L,R)cerr<<a[_x]<<" ";cerr<<endl;
using namespace std;
typedef long long LL;
LL read(){
    LL x=0,f=0;
    char ch=getchar();
    while (!isdigit(ch))
        f|=ch=='-',ch=getchar();
    while (isdigit(ch))
        x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    return f?-x:x;
}
typedef __int128 LG;
const int N=105,mod=998244353;
int Pow(int x,int y){
    int ans=1;
    for (;y;y>>=1,x=(LL)x*x%mod)
        if (y&1)
            ans=(LL)ans*x%mod;
    return ans;
}
void Add(int &x,int y){
    if ((x+=y)>=mod)
        x-=mod;
}
void Del(int &x,int y){
    if ((x-=y)<0)
        x+=mod;
}
int Add(int x){
    return x>=mod?x-mod:x;
}
int Del(int x){
    return x<0?x+mod:x;
}
int n;
char s[N];
int a[N];
int pw2[N];
map <LG,int> dp,vis;
void write(LG x){
    if (x>9)
        write(x/10);
    putchar('0'+x%10);
}
LG Get(LG a,int L,int R){
    return a>>L&(((LG)1<<(R-L+1))-1);
}
int DP(LG K){
    if (vis[K])
        return dp[K];
    vis[K]=1;
    int ans=0,k=K>>n;
    if (!k)
        return dp[K]=1;
    LG S=Get(K,0,n-1);
    For(i,0,k-1)
        if (S>>i&1)
            ans++;
    ans=pw2[ans];
    int cnt=0;
    For(i,0,k-1){
        For(j,i,k-1){
            int len=j-i+1;
            if (j+len>k-1)
                break;
            LG v=Get(S,i,j);
            for (int t=i+len;t+len-1<k;t+=len){
                v&=Get(S,t,t+len-1);
                Add(ans,(LL)pw2[cnt]*DP(v|(LG)len<<n)%mod
                        *DP(Get(S,t+len,k-1)|(LG)(k-(t+len))<<n)%mod);
            }
        }
        if (S>>i&1)
            cnt++;
    }
    return dp[K]=ans;
}
int main(){
    cin>>s;
    n=strlen(s);
    pw2[0]=1;
    For(i,1,n)
        pw2[i]=Add(pw2[i-1]<<1);
    For(i,0,n-1)
        a[i]=s[i]-'0';
    LG S=0;
    For(i,0,n-1)
        S|=(LG)a[i]<<i;
    S|=(LG)n<<n;
    write(DP(S));
    puts("");
    return 0;
}

原文地址:https://www.cnblogs.com/zhouzhendong/p/AGC020E.html

时间: 2024-07-30 15:36:54

AtCoder Grand Contest 020 (AGC020) E - Encoding Subsets 动态规划的相关文章

【Atcoder Grand Contest 020 E】 Encoding Subsets

Atcoder Grand Contest 020 E 题意:给一个\(0-1\)字符串,如果其中有一段重复,就可以表示成\((\)这一块的表示\(\times\)出现次数\()\). 问这个字符串的所有子集中有多少种表示方法. 思路:考虑\(dp(s)\)表示字符串\(s\)的答案. 那么我们得考虑第一个表示成的位置是什么. ①第一位就是表示的第一位,不参与循环.那么转移到\(dp(s.substr(1))\),并且如果这位是\(1\),那么乘上\(2\),因为这位可能是\(0\). ②一个前

AtCoder Grand Contest 020 题解

传送门 怎么又是\(tourist\)神仙的题-- \(A\) 咕咕 int n,a,b; int main(){ scanf("%d%d%d",&n,&a,&b); puts(((b-a-1)&1)?"Alice":"Borys"); return 0; } \(B\) 考虑从后往前做,假设考虑到\(a_i\),且只考虑第\(a_{i+1}\)到\(a_n\)的答案为\(s\),那么考虑了\(a_i\)的答案\(

AtCoder Grand Contest 002 (AGC002) F - Leftmost Ball 动态规划 排列组合

原文链接https://www.cnblogs.com/zhouzhendong/p/AGC002F.html 题目传送门 - AGC002F 题意 给定 $n,k$ ,表示有 $n\times k$ 个球,其中,颜色为 $1,2,\cdots, n$ 的球各有 $k$ 个. 将这些球任意排列成一排,对于每一种颜色,将这种颜色的球的最左边的那个涂成颜色 $0$ . 问最终可以得到多少种不同的排列. $1\leq n,k\leq 2000,{\rm Mod} = 10^9 +7$ 题解 首先当 $

AtCoder Grand Contest 025 Problem D

www.cnblogs.com/shaokele/ AtCoder Grand Contest 025 Problem D Time Limit: 2 Sec Memory Limit: 1024 MB Description Takahashi is doing a research on sets of points in a plane. Takahashi thinks a set \(S\) of points in a coordinate plane is a good set w

AtCoder Grand Contest 024 Problem E(动态规划)

www.cnblogs.com/shaokele/ AtCoder Grand Contest 024 Problem E Time Limit: 2 Sec Memory Limit: 1024 MB Description Find the number of the possible tuples of sequences (\(A_0,A_1,-,A_N\)) that satisfy all of the following conditions, modulo \(M\): ? Fo

AtCoder Grand Contest 011

AtCoder Grand Contest 011 upd:这篇咕了好久,前面几题是三周以前写的... AtCoder Grand Contest 011 A - Airport Bus 翻译 有\(n\)个乘客到达了飞机场,现在他们都要坐车离开机场.第\(i\)个乘客到达的时间是\(T_i\),一个乘客必须在\([T_i,T_i+k]\)时刻做到车,否则他会生气.一辆车最多可以坐\(C\)个人.问最少安排几辆车可以让所有人都不生气. 题解 从前往后贪心即可. #include<iostream

AtCoder Grand Contest 014

AtCoder Grand Contest 014 A - Cookie Exchanges 有三个人,分别有\(A,B,C\)块饼干,每次每个人都会把自己的饼干分成相等的两份然后给其他两个人.当其中有一个人的饼干数量是奇数的时候停止,求会进行几次这样子的操作,或者会永远进行下去. 首先无解的情况一定是三个数都是相等的偶数. 否则直接暴力模拟就行了.(盲猜答案不会很大) 证明一下答案的范围:不妨令\(A\le B\le C\),那么最大值和最小值之间的差就是\(C-A\),那么执行完一次操作之后

AtCoder Grand Contest 016

AtCoder Grand Contest 016 A - Shrinking 你可以进行一个串的变换,把一个长度为\(n\)的串\(S\)可以变成长度为\(n-1\)的串\(T\),其中\(T_i\)要么是\(S_i\)要么是\(S_{i+1}\). 现在问你最少进行多少次这个操作,能够使最终得到的\(T\)只由一个字符构成. \(|S|\le 100\) 首先枚举最终字符是哪一个.那么首先在\(S\)末尾加上一个这个字符,那么这个最小步数等于对于所有位置而言,离它最近的枚举的字符到这个位置的

Atcoder Grand Contest 018 E - Sightseeing Plan

Atcoder Grand Contest 018 E - Sightseeing Plan 枚举从第二个矩形的 \((x_1,y_1)\) 进入,\((x_2,y_2)\) 出来,那么中间可以选的点的数量是 \(x_2+y_2-x_1-x_2+1\) ,也就是说对于每一条合法路线,从 \((x_1,y_1)\) 进入的贡献为 \(-x_1-x_2\) ,从 \((x_2,y_2)\) 出来的贡献为 \(x_2+y_2+1\) ,枚举一下第二个矩形边界上的点,我们只需要分别计算某个点到第一个矩形