zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 94 Editorial F

    复杂度的问题(题解在下面)

    x <= 20, 我们可以, 暴力把所有的 x-prime 跑出来, 这是跑出 x = 1 ~ 20 并插入ac自动机 每次 大约 所需要计算次数

    #include <bits/stdc++.h>
    #define all(n) (n).begin(), (n).end()
    #define se second
    #define fi first
    #define pb push_back
    #define mp make_pair
    #define sqr(n) (n)*(n)
    #define rep(i,a,b) for(int i=(a);i<=(b);++i)
    #define per(i,a,b) for(int i=(a);i>=(b);--i)
    #define IOS ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr)
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> PII;
    typedef pair<ll, ll> PLL;
    typedef vector<int> VI;
    
    const int N = 3e5 + 5;
    
    int n, m, _, k;
    int a[21];
    long long ans = 0;
    
    bool check(int k) {
        rep (i, 1, n) {
            int cur = 0;
            rep (j, i, n) {
                ans += 3;
                cur += a[j];
                if (cur != n && n % cur == 0) return 0;
            }
        }
        return 1;
    }
    
    void dfs(int x, int y) {
        if (!y) {
            if (check(x - 1)) ans += (x << 1);
            return;
        }
        rep (i, 1, min(y, 9)) ans += 4, a[x] = i, dfs(x + 1, y - i);
    }
    
    int main() {
        IOS; 
        rep (i, 1, 20) ans = 0, dfs(1, i), cout << ans << '
    ';
        return 0;
    }
    

    1~20 所需的计算数量

    8
    22
    52
    116
    252
    540
    1148
    2428
    5116
    10740
    22492
    47000
    98020
    204060
    424124
    880188
    1824124
    3775484
    7804924
    16116742
    

    不会超过2e8的数量级, 也就是1s可以跑出来, 题目给的是2s, 剩下的时间可以用来解决本题

    题解

    暴力跑出所有符合 x-prime 的字符串加入ac自动机

    f[i][j] 表示字符串 第i个字符处在 自动机第 j 个节点,, 的最小花费

    只要转移的时候不走到自动机的字符串结尾节点, 就不会有 x-prime, 哪怕你在节点 0

    #include <bits/stdc++.h>
    #define all(n) (n).begin(), (n).end()
    #define se second
    #define fi first
    #define pb push_back
    #define mp make_pair
    #define sqr(n) (n)*(n)
    #define rep(i,a,b) for(int i=(a);i<=(b);++i)
    #define per(i,a,b) for(int i=(a);i>=(b);--i)
    #define IOS ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr)
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> PII;
    typedef pair<ll, ll> PLL;
    typedef vector<int> VI;
    
    const int N = 5e3 + 5;
    
    int n, m, _, k;
    int a[21], x, len = 1;
    int f[2][N];
    char s[1005];
    
    namespace AC {
    	const int C = 1;
    	const int M = 9;
    
    	struct ACstruct {
    		int trie[N][M], fail[N];
    		bool ended[N];
    		int q[N], tot;
    
    		void insert(int k) {
    			int p = 0;
    			rep(i, 1, k) {
    				int ch = a[i] - C;
    				if (!trie[p][ch]) trie[p][ch] = ++tot;
    				p = trie[p][ch];
    			}
    			ended[p] = 1;
    		}
    
    		void build() {
    			int head = 0, tail = -1;
    			rep(i, 0, M - 1)
    				if (trie[0][i])
    					q[++tail] = trie[0][i];
    			while (head <= tail) {
    				int p = q[head++];
    				rep(i, 0, M - 1)
    					if (trie[p][i])
    						fail[trie[p][i]] = trie[fail[p]][i],
    						q[++tail] = trie[p][i];
    					else trie[p][i] = trie[fail[p]][i];
    			}
    		}
    	}ac;
    }
    
    bool check(int k) {
    	rep(i, 1, k) {
    		int cur = 0;
    		rep(j, i, k) {
    			cur += a[j];
    			if (cur != x && x % cur == 0) return 0;
    		}
    	}
    	return 1;
    }
    
    void dfs(int x, int y) {
    	if (!y) {
    		if (check(x - 1)) AC::ac.insert(x - 1);
    		return;
    	}
    	rep(i, 1, min(y, 9)) a[x] = i, dfs(x + 1, y - i);
    }
    
    int main() {
    	IOS; cin >> s + 1 >> x;
    	memset(f[0], 0x3f, sizeof f[0]);
    	dfs(1, x); AC::ac.build();
        f[0][0] = 0;
    	for (int& i = len; s[i]; ++i) {
    		int a = i & 1, b = a ^ 1, ch = s[i] - '1';
    		memset(f[a], 0x3f, sizeof f[a]);
    		rep(j, 0, AC::ac.tot)
    			if (f[b][j] != 0x3f3f3f3f) {
    				f[a][j] = min(f[a][j], f[b][j] + 1);
    				int v = AC::ac.trie[j][ch];
    				if (!AC::ac.ended[v]) f[a][v] = min(f[a][v], f[b][j]);
    			}
    	}--len;
    	int ans = len;
    	rep(i, 0, AC::ac.tot) ans = min(ans, f[len & 1][i]);
    	cout << ans;
    	return 0;
    }
    
  • 相关阅读:
    php冒泡排序
    解决ubuntu下安装phpmyadmin访问不了的问题
    反省
    mysql主从复制
    ubuntu14.04 安装 bcm43142无线网卡
    mysql 批量更新和批量插入
    chromium 安装 pepper flash player
    js prototype新感悟
    读《乌合之众》
    马云---我的世界永不言败
  • 原文地址:https://www.cnblogs.com/2aptx4869/p/13629226.html
Copyright © 2011-2022 走看看