「6月雅礼集训 2017 Day4」暴力大神hxx

Posted 逢山开路 遇水架桥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了「6月雅礼集训 2017 Day4」暴力大神hxx相关的知识,希望对你有一定的参考价值。

【题目大意】

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

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

$1 \leq n \leq 26, 1\leq 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

 

以上是关于「6月雅礼集训 2017 Day4」暴力大神hxx的主要内容,如果未能解决你的问题,请参考以下文章

「6月雅礼集训 2017 Day5」吃干饭

2017雅礼集训 Day4

雅礼集训——day3day4

LOJ #6035.「雅礼集训 2017 Day4」洗衣服 贪心

「6月雅礼集训 2017 Day11」tree

「6月雅礼集训 2017 Day10」quote