求助一下,总点数是1e5但是边数开2e5或1e6都会RE,开到2e6才能过
查看原帖
求助一下,总点数是1e5但是边数开2e5或1e6都会RE,开到2e6才能过
362938
Tsawke楼主2023/1/17 16:44

如题,不太明白是我哪里写错了,用到 new 的只有建边的时候,但是 ed 按照一般思路开到 2e52e5 就会 RE 一个点。

#define _USE_MATH_DEFINES
#include <bits/stdc++.h>

#define PI M_PI
#define E M_E
#define npt nullptr
#define SON i->to
#define OPNEW void* operator new(size_t)
#define ROPNEW void* Edge::operator new(size_t){static Edge* P = ed; return P++;}

using namespace std;

mt19937 rnd(random_device{}());
int rndd(int l, int r){return rnd() % (r - l + 1) + l;}
bool rnddd(int x){return rndd(1, 100) <= x;}

typedef unsigned int uint;
typedef unsigned long long unll;
typedef long long ll;
typedef long double ld;

#define MOD (ll)(1e9 + 7)
#define S(name, idx) ((name) & (1 << ((idx) - 1)))

template < typename T = int >
inline T read(void);

struct Edge{
    Edge* nxt;
    int to;
    OPNEW;
}ed[2100000];
ROPNEW;
Edge* head[110000];

int N, K;
int Smx;
int opt[10][10];
struct Node{int S; int col;};
basic_string < Node > legal[40];
ll dp[110000][40][6];
ll merg[40][6];

void Clear(void){
    for(int i = 0; i <= Smx; ++i)legal[i].clear();
    for(int i = 0; i <= N; ++i)head[i] = npt;
    for(int i = 0; i <= N; ++i)for(int S = 0; S <= Smx; ++S)for(int k = 1; k <= K; ++k)dp[i][S][k] = 0;
}
void TreeDP(int p = 1, int fa = 0){
    for(auto i = head[p]; i; i = i->nxt)if(SON != fa)TreeDP(SON, p);
    if(p != 1 && !head[p]->nxt){for(int i = 0; i < K; ++i)dp[p][1 << i][i + 1] = 1; return;}
    memset(merg, 0, sizeof merg);
    bool isbeg(true);
    for(auto i = head[p]; i; i = i->nxt){
        if(SON == fa)continue;
        if(isbeg){
            isbeg = false;
            for(int S = 1; S <= Smx; ++S)for(int j = 1; j <= K; ++j)for(int k = 1; k <= K; ++k)(merg[S][j] += dp[SON][S][k]) %= MOD;
            // printf("p is %d, after merge, merge is : \n", p);
            // for(int S = 1; S <= Smx; ++S)for(int i = 1; i <= K; ++i)
            //     cout << "merg[" << i << "][" << bitset < 5 >(S) << "] = " << merg[S][i] << endl;
            continue;
        }
        ll lst[40][6];
        for(int S = 0; S <= Smx; ++S)for(int j = 1; j <= K; ++j)lst[S][j] = merg[S][j], merg[S][j] = 0;
        ll sum[40]; memset(sum, 0, sizeof sum);
        for(int S = 1; S <= Smx; ++S)for(int j = 1; j <= K; ++j)(sum[S] += dp[SON][S][j]) %= MOD;
        for(int S1 = 1; S1 <= Smx; ++S1)
            for(auto S2 : legal[S1])
                (merg[S1 | S2.S][S2.col] += lst[S1][S2.col] * sum[S2.S] % MOD) %= MOD;
        // printf("p is %d, after merge, merge is : \n", p);
        // for(int S = 1; S <= Smx; ++S)for(int i = 1; i <= K; ++i)
        //     cout << "merg[" << i << "][" << bitset < 5 >(S) << "] = " << merg[S][i] << endl;
    }
    for(int S = 1; S <= Smx; ++S)
        for(int i = 1; i <= K; ++i)
            (dp[p][S | (1 << (i - 1))][i] += merg[S][i]) %= MOD;
    // printf("p = %d\n", p);
    // for(int S = 1; S <= Smx; ++S)
    //     for(int i = 1; i <= K; ++i){
            
    //         printf("dp[%d][", i); cout << bitset < 5 >(S); printf("] = %lld\n", dp[p][S][i]);
    //     }
}

int main(){
    // freopen("color.in", "r", stdin);
    // freopen("color.out", "w", stdout);
    int T = read();
    while(T--){
        Clear();
        N = read(), K = read();
        Smx = (1 << K) - 1;
        for(int i = 1; i <= K; ++i)for(int j = 1; j <= K; ++j)opt[i][j] = read();
        for(int i = 2; i <= N; ++i){
            int s = i, t = read();
            head[s] = new Edge{head[s], t};
            head[t] = new Edge{head[t], s};
        }
        for(int S1 = Smx; S1; S1 = (S1 - 1) & Smx)
            for(int S2 = Smx; S2; S2 = (S2 - 1) & Smx){
                int cur(-1);
                bool flag(true);
                for(int i = 1; i <= K; ++i){
                    if(!flag)break;
                    for(int j = 1; j <= K; ++j){
                        if(!flag)break;
                        if(S(S1, i) && S(S2, j)){
                            if(opt[i][j] != opt[j][i]){flag = false; break;}
                            if(!~cur)cur = opt[i][j];
                            else if(opt[i][j] != cur)flag = false;
                        }
                    }
                }if(flag)legal[S1] += Node{S2, cur};
            }
        // for(int S = 1; S <= Smx; ++S)for(auto S2 : legal[S]){
        //     cout << bitset < 5 >(S) << "with" << bitset < 5 >(S2.S) << "  col is" << S2.col << endl;
        // }
        TreeDP();
        // for(int i = 1; i <= N; ++i)for(int S = 1; S <= Smx; ++S)for(int j = 1; j <= K; ++j)
        //     cout << "dp[" << i << "][" << j << "][" << bitset < 5 >(S) << "] = " << dp[i][S][j] << endl;
        ll ans(0);
        for(int S = 1; S <= Smx; ++S)for(int i = 1; i <= K; ++i)(ans += dp[1][S][i]) %= MOD;
        printf("%lld\n", ans);
    }
    fprintf(stderr, "Time: %.6lf\n", (double)clock() / CLOCKS_PER_SEC);
    return 0;
}

template < typename T >
inline T read(void){
    T ret(0);
    int flag(1);
    char c = getchar();
    while(c != '-' && !isdigit(c))c = getchar();
    if(c == '-')flag = -1, c = getchar();
    while(isdigit(c)){
        ret *= 10;
        ret += int(c - '0');
        c = getchar();
    }
    ret *= flag;
    return ret;
}

/*

2
5 2
1 2
2 1
1 2 1 4
5 2
1 2
1 1
1 2 1 4

*/
2023/1/17 16:44
加载中...