暴力TLE求助
查看原帖
暴力TLE求助
357906
爆雪骑士楼主2024/11/28 11:15

rt,期望#1-3 测了好多组n,w <= 18都没问题,为什么测试点T了啊

#include <bits/stdc++.h>
#define ll long long
using namespace std;

const int N = 3e5+50,log3n = 12;
int n,w;
struct edge{int to,next;}e[6*N];
int head[N],cnt;
void add(int u,int v){
    e[++cnt] = {v,head[u]},head[u] = cnt;
    e[++cnt] = {u,head[v]},head[v] = cnt;
}
int highbit(int x){
    int p = 0;
    while(x){
        x /= 3;
        p++;
    }
    return p;
}

int pb[log3n+5];
/*
bool fit(int x){
    int p = 0,cpx = x;
    while(x){
        x /= 3;
        p++;
    }
    x = cpx;
    p-=2;
    x /= pb[p];
    return (x%3 == 0);
}
*/
/*
bool vis[N],vis1[N],vis2[N];
bool dfs(int u,int fa,int s,int t){
    if(u == t){
        vis[u] = 1;
        return 1;
    }
    bool ans1 = 0,ans2 = 1;
    for (int i = head[u];i;i = e[i].next){
        int v = e[i].to;
        if(v == fa) continue;
        if(vis[v] || dfs(v,u,s,t)){
            ans1 = 1;
            vis[u] = 1;
        }
    }
    return ans1;
}
*/
int dfn[N],low[N],idx;
bool cut[N];
void tarjan(int u,int fa){
    dfn[u] = low[u] = ++idx;
    int son = 0;
    for (int i = head[u];i;i = e[i].next){
        int v = e[i].to;
        if(v == fa) continue;
        if(!dfn[v]){
            tarjan(v,u);
            low[u] = min(low[u],low[v]);
            son++;
            if(fa != -1 && low[v] >= dfn[u]) cut[u] = 1;
        }
        else{
            low[u] = min(low[u],dfn[v]);
        }
    }
    if(fa == -1 && son >= 2) cut[u] = 1;
}
bool vis[N][2];
bool dfs(int u,int fa,int t){
    if(u == t){
        return vis[u][0] = vis[u][1] = 1;
    }
    vis[u][0] = 1;
    for (int i = head[u];i;i = e[i].next){
        int v = e[i].to;
        if(v == fa || vis[v][0]) continue;
        dfs(v,u,t);
        vis[u][1] |= vis[v][1];
    }
}
bool start[N],block[N],vis2[N];
void dfs2(int u,int fa){
    vis2[u] = 1;
    for (int i = head[u];i;i = e[i].next){
        int v = e[i].to;
        if(v == fa || block[v] || vis2[v]) continue;
        dfs2(v,u);
    }
}
void init(){
    memset(vis,0,sizeof(vis));
    memset(start,0,sizeof(start));
    memset(block,0,sizeof(block));
    memset(vis2,0,sizeof(vis2));
}
ll ans[N];
int main()
{
    freopen("P11220.in","r",stdin);
    freopen("P11220.out","w",stdout);
    scanf("%d%d",&n,&w);
    if(w == 0){
        for (int i = 0;i <= n;i++) printf("%lld\n",1ll*n*(n+1));
        return 0;
    }
    pb[0] = 1;
    for (int i = 1;i <= log3n;i++) pb[i] = 3*pb[i-1];
    for (int i = 0;i <= n;i++){
       // if(i > 2)  add(i,i/3);
        for (int j = 0;j < 3;j++){
            if(i*3+j <= n && i != i*3+j){
                add(i,i*3+j);
            }
        }
        if(i <= w && i%3 != 0){
            int top = highbit(i)-1,remain = i%3;
            int to = remain*pb[top]+i/3;
            if(to != i && to <= n) add(i,to);
       //     printf("%d %d\n",i,to);
        }
        /*
        if(i > 2 && fit(i)){
            int top = highbit(i)-1,remain = i/pb[top];
            int to = (i-remain*pb[top])*3+remain;
            if(to <= w) add(i,to);
        }
        */
    }
/*
    for (int u = 0;u <= n;u++){
        printf("%d ",u);
        for (int i = head[u];i;i = e[i].next){
            int v = e[i].to;
            printf("%d ",v);
        }
        printf("\n");
    }
*/
    /*
    for (int x = 0;x <= n;x++){
        for (int y = x+1;y <= n;y++){
            dfs(x,x,y);
        }
    }
    */
    tarjan(0,-1);
/*
    for (int i = 0;i <= n;i++) printf("%d ",dfn[i]);
    printf("\n");
    for (int i = 0;i <= n;i++) printf("%d ",cut[i]);
    printf("\n");
*/
    for (int x = 0;x <= n;x++){
        for (int y = x+1;y <= n;y++){
            init();
            dfs(x,x,y);
            /*
            printf("%d %d ",x,y);
            for (int i = 0;i <= n;i++) printf("%d ",vis[i][1]);
            printf("\n");
            */
            for (int i = 0;i <= n;i++){
                if(vis[i][1]){
                    if(cut[i] || i == x || i == y) start[i] = 1;
                    else block[i] = 1;
                }
            }
            /*
            for (int i = 0;i <= n;i++) printf("%d ",vis2[i]);
            printf("\n");
            */
            for (int i = 0;i <= n;i++){
                if(start[i] && !vis2[i]){
                    dfs2(i,-1);
                }
            }
            /*
            for (int i = 0;i <= n;i++) printf("%d ",vis2[i]);
            printf("\n");
            */
            for (int i = 0;i <= n;i++){
                if(vis2[i]) ans[i]+=2;
            }
        }
    }
    for (int i = 0;i <= n;i++) printf("%lld\n",ans[i]);
    fclose(stdin);
    fclose(stdout);
    return 0;
}

2024/11/28 11:15
加载中...