zoukankan      html  css  js  c++  java
  • 「6月雅礼集训 2017 Day4」暴力大神hxx

    【题目大意】

    给出一个n重循环,每重循环有范围$[l, r]$,其中$l$,$r$可能是之前的变量,也可能是常数。求循环最底层被执行了多少次。

    其中,保证每个循环的$l$,$r$最多有一个是之前的变量。设所有常数最大值为C。

    $1 leq n leq 26, 1leq C leq 10^5$

    【题解】

    发现构成了一个森林。

    树形dp,稍微推一些循环交换顺序等等的性质,然后乘在一起就行了。

    大概设f[x,i]表示到了x这个点,x的取值为i,x的子树的执行次数。

    转移用个前缀和优化即可。复杂度$O(nC)$

    # include <stdio.h>
    # include <string.h>
    # include <iostream>
    # include <algorithm>
    
    using namespace std;
    
    typedef long long ll;
    typedef unsigned long long ull;
    typedef long double ld;
    
    const int M = 1e5 + 10, N = 27;
    const int mod = 12015858;
    
    int n;
    int l[N], r[N];
    
    char str[N];
    inline void gin(int &x) {
        scanf("%s", str);
        if(!isdigit(str[0])) x = -(str[0] - 'a' + 1);
        else {
            x = 0;
            for (int i=0; str[i]; ++i) x = (x<<3) + (x<<1) + str[i] - '0';
        }
    }
    
    int head[N], nxt[M], to[M], tot = 0;
    inline void add(int u, int v) {
        ++tot; nxt[tot] = head[u]; head[u] = tot; to[tot] = v;
    }
    inline void adde(int u, int v) {
    //    cout << u << " --> " << v << endl;
        add(u, v), add(v, u);
    }
    
    
    int f[N][M], s[N][M];
    // 到了x这个点,x的取值为i 
    inline void dfs(int x, int fa = 0) {
        for (int i=1; i<=100000; ++i) f[x][i] = 1;
        for (int i=head[x]; i; i=nxt[i]) {
            if(to[i] == fa) continue;
            dfs(to[i], x);
            int y = to[i];
            for (int j=1; j<=100000; ++j) {
                if(l[y] < 0) {
                    if(j <= r[y]) f[x][j] = 1ll * f[x][j] * (s[y][r[y]] - s[y][j-1]) % mod;
                    else f[x][j] = 0;
                }
                if(r[y] < 0) {
                    if(l[y] <= j) f[x][j] = 1ll * f[x][j] * (s[y][j] - s[y][l[y]-1]) % mod;
                    else f[x][j] = 0;
                }
                if(f[x][j] < 0) f[x][j] += mod;
            }
        }
        for (int i=1; i<=100000; ++i) {
            s[x][i] = s[x][i-1] + f[x][i];
            if(s[x][i] >= mod) s[x][i] -= mod;
    //        if(i <= 100) cout << x << ' ' << i << ' ' << f[x][i] << endl;
        }
    }
    
    
    int main() {
    //    freopen("car.in", "r", stdin);
    //    freopen("car.out", "w", stdout);
        cin >> n;
        for (int i=1; i<=n; ++i) {
            gin(l[i]), gin(r[i]);
        //    cout << l[i] << ' ' << r[i] << endl;
            if(l[i] < 0) adde(-l[i], i);
            if(r[i] < 0) adde(-r[i], i);
        }
        
        ll ans = 1, times;
        for (int i=1; i<=n; ++i) {
            if(l[i] < 0 || r[i] < 0) continue;
            dfs(i); 
            ans = ans * (s[i][r[i]] - s[i][l[i]-1]) % mod;
        }
        ans = (ans + mod) % mod;
        cout << ans;
    
        return 0;
    }
    View Code
  • 相关阅读:
    Android studio 报错 installation failed with message failed to finalize session:INSTALL_FAILED_INVALID_APK 解决方法
    Python 爬虫入门实例(爬取小米应用商店的top应用apk)
    解决jenkins控制台中文乱码问题
    四.Jenkins的授权和访问控制
    三.jenkins 在windows上配置master 和 agent(slave)
    Jenkins 默认没有Launch agent via Java Web Start,该如何配置
    二.jenkins构建自动化任务
    一.Jenkins的windows安装
    maven仓库地址配置
    jvm linux 时区设置
  • 原文地址:https://www.cnblogs.com/galaxies/p/20170620_a.html
Copyright © 2011-2022 走看看