蚂 蜂 良 好 , WA on#4#5#6求调,悬三关

P2272 [ZJOI2007] 最大半连通子图

__builtin_orz @ 2024-09-06 11:54:58

#include<algorithm>
#include<cctype>
#include<cstdio>
#include<cstdlib>
#include<ctime>
#include<queue>
#include<functional>
#ifdef _WIN32
#define getchar _getchar_nolock
#define putchar _putchar_nolock
#else
#define getchar getchar_unlocked
#define puhchar putchar_unlocked
#endif
#define _N_ 1000005
#define _M_ 10000006
#define MAYBE(ptr,attr)(ptr?ptr->attr:decltype(ptr->attr){})
#define int __uint128_t
int read(){
    int x=0,ch;
    while(!isdigit(ch=getchar()));
    do x=x*10+ch-'0';while(isdigit(ch=getchar()));
    return x;
}
void write(int x,int step=' '){
    static int o[505];
    int tp=0;
    while(x>9)o[++tp]=x%10+'0',x/=10;
    putchar(x+'0');
    while(tp)putchar(o[tp--]);
    putchar(step);
}
void new_line(){putchar('\n');}
struct Treap{
    Treap *ch[2];
    int val,rnk;
    Treap(int v){
        val=v;
        rnk=rand();
        ch[0]=ch[1]=nullptr;
    }
}*DAG_to[_N_];
void Treap_rotate(Treap *&now,int c){
    Treap *tmp=now->ch[c];
    now->ch[c]=tmp->ch[!c];
    tmp->ch[!c]=now;
    now=tmp;
}
void Treap_insert(Treap *&now,int x){
    if(!now)now=new Treap(x);
    else if(x<now->val){
        Treap_insert(now->ch[0],x);
        if(now->ch[0]->rnk<now->rnk)
            Treap_rotate(now,0);
    }else if(x>now->val){
        Treap_insert(now->ch[1],x);
        if(now->ch[1]->rnk<now->rnk)
            Treap_rotate(now,1);
    }
}
void Treap_each(Treap *now,std::function<void(int)>f){
    if(now){
        f(now->val);
        Treap_each(now->ch[0],f);
        Treap_each(now->ch[1],f);
    }
}
struct CFS{
    int val;
    CFS *nxt;
    CFS(int val,CFS *nxt=nullptr):val(val),nxt(nxt){}
}*G_to[_N_];
void CFS_add_edge(CFS *&head,int val){head=new CFS(val,head);}
void CFS_each(CFS *head,std::function<void(int)>f){
    for(CFS *i=head;i;i=i->nxt)
        f(i->val);
}
#define EACH(type,name,...)type##_each(name,[&](__VA_ARGS__){
#define END });
int SCC_low[_N_],SCC_dfn[_N_],SCC_dfn_cnt;
int SCC_stk[_N_],SCC_top;
int SCC_scc[_N_],SCC_scc_cnt;
int SCC_scc_siz[_N_];
void tarjan(int now){
    now[SCC_low]=now[SCC_dfn]=++SCC_dfn_cnt;
    SCC_stk[++SCC_top]=now;
    EACH(CFS,G_to[now],int to)
        if(!to[SCC_dfn]){
            tarjan(to);
            now[SCC_low]=std::min(now[SCC_low],to[SCC_low]);
        }else if(!to[SCC_scc])
            now[SCC_low]=std::min(now[SCC_low],to[SCC_dfn]);
    END
    if(now[SCC_dfn]==now[SCC_low]){
        SCC_scc_cnt++;
        int tmp;
        do{
            tmp=SCC_stk[SCC_top];
            tmp[SCC_scc]=SCC_scc_cnt;
            SCC_scc_cnt[SCC_scc_siz]++;
            SCC_top--;
        }while(tmp!=now);
    }
}
int ans[_N_],kind[_N_];
void topo(int now){
    now[ans]=now[SCC_scc_siz];
    now[kind]=1;
    int delta=0;
    EACH(Treap,now[DAG_to],int to)
        if(!to[ans])
            topo(to);
        if(to[ans]>delta){
            delta=to[ans];
            now[kind]=0;
        }
        if(to[ans]==delta)
            now[kind]++;
    END
    now[ans]+=delta;
}
signed main(){
    srand(time(nullptr));
    int n=read(),m=read(),MOD=read();
    for(int i=1;i<=m;i++){
        int f=read(),t=read();
        CFS_add_edge(G_to[f],t);
    }
    for(int i=1;i<=n;i++)
        if(!SCC_scc[i])
            tarjan(i);
    for(int i=1;i<=n;i++)
        EACH(CFS,G_to[i],int to)
            if(i[SCC_scc]!=to[SCC_scc])
                Treap_insert(i[SCC_scc][DAG_to],to[SCC_scc]);
        END
    int real_ans=0,real_kind=0;;
    for(int i=1;i<=SCC_scc_cnt;i++){
        if(!i[ans])
            topo(i);
        if(i[ans]>real_ans){
            real_ans=i[ans];
            real_kind=0;
        }
        if(i[ans]==real_ans)
            real_kind=(real_kind+i[kind])%MOD;
    }
    write(real_ans,'\n');
    write(real_kind);
    return 0;
}

by Cuxhin @ 2024-09-06 11:57:16

蚂蜂太差,不看


by Amadeus004 @ 2024-09-06 12:00:33

这码量都快赶上树剖+可持久化线段树了


|