QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#404022#4408. 燃烧的呐球zjy0001100 ✓2959ms250868kbC++1714.5kb2024-05-03 09:12:312024-05-03 09:12:33

Judging History

你现在查看的是最新测评结果

  • [2024-05-03 09:12:33]
  • 评测
  • 测评结果:100
  • 用时:2959ms
  • 内存:250868kb
  • [2024-05-03 09:12:31]
  • 提交

answer

#include<bits/stdc++.h>
#define LL long long
#define LLL __int128
#define uint unsigned
#define ldb long double
#define uLL unsigned long long
using namespace std;
namespace FastIO
{
// ------------------------------
// #define DISABLE_MMAP
// ------------------------------
#if ( defined(LOCAL) || defined(_WIN32) ) && !defined(DISABLE_MMAP)
#define DISABLE_MMAP
#endif
#if __cplusplus > 201700
#define inline_v inline
#else
#define inline_v
#endif
#ifdef LOCAL
	inline char gc() { return getchar(); }
	inline void pc(char c) { putchar(c); }
#else
#ifdef DISABLE_MMAP
	inline_v constexpr int _READ_SIZE = 1 << 18;
	inline_v static char _read_buffer[_READ_SIZE], *_read_ptr = nullptr, *_read_ptr_end = nullptr;
	inline char gc()
	{
		if ( __builtin_expect(_read_ptr == _read_ptr_end, false) )
		{
			_read_ptr = _read_buffer, _read_ptr_end = _read_buffer + fread(_read_buffer, 1, _READ_SIZE, stdin);
			if ( __builtin_expect(_read_ptr == _read_ptr_end, false) ) return EOF;
		}
		return *_read_ptr++;
	}
#else
#include<sys/mman.h>
	inline_v static const char *_read_ptr = (const char *)mmap(nullptr, 0x7fffffff, 1, 2, 0, 0);
	inline char gc() { return *_read_ptr++; }
#endif
	inline_v constexpr int _WRITE_SIZE = 1 << 18;
	inline_v static char _write_buffer[_WRITE_SIZE], *_write_ptr = _write_buffer;
	inline void pc(char c)
	{
		*_write_ptr++ = c;
		if ( __builtin_expect(_write_buffer + _WRITE_SIZE == _write_ptr, false) )
			fwrite(_write_buffer, 1, _write_ptr - _write_buffer, stdout), _write_ptr = _write_buffer;
	}
	inline_v struct _auto_flush
	{
		inline ~_auto_flush() { fwrite(_write_buffer, 1, _write_ptr - _write_buffer, stdout); }
	}	_auto_flush;
#endif
	template < class T > inline_v constexpr bool _is_signed = numeric_limits < T >::is_signed;
	template < class T > inline_v constexpr bool _is_unsigned = numeric_limits < T >::is_integer && !_is_signed < T >;
#if __SIZEOF_LONG__ == 64
	template <> inline constexpr bool _is_signed < __int128 > = true;
	template <> inline constexpr bool _is_unsigned < __uint128_t > = true;
#endif
	inline void read(char &c) { do c = gc(); while ( !isgraph(c) ); }
	inline void read_cstr(char *s)
	{
		char c = gc(); while ( !isgraph(c) ) c = gc();
		while ( isgraph(c) ) *s++ = c, c = gc();
        *s = 0;
	}
	inline void read(string &s)
	{
		char c = gc(); s.clear(); while ( !isgraph(c) ) c = gc();
		while ( isgraph(c) ) s.push_back(c), c = gc();
	}
	template < class T, enable_if_t < _is_signed < T >, int > = 0 >
	inline void read(T &x)
	{
		char c = gc(); bool f = true; x = 0;
		while ( !isdigit(c) ) { if ( c == 45 ) f = false; c = gc(); }
		if ( f ) while ( isdigit(c) ) x = x * 10 + ( c & 15 ), c = gc();
		else     while ( isdigit(c) ) x = x * 10 - ( c & 15 ), c = gc();
	}
	template < class T, enable_if_t < _is_unsigned < T >, int > = 0 >
	inline void read(T &x)
	{
		char c = gc(); while ( !isdigit(c) ) c = gc();
		x = 0; while ( isdigit(c) ) x = x * 10 + ( c & 15 ), c = gc();
	}
	inline void write(char c) { pc(c); }
	inline void write_cstr(const char *s) { while ( *s ) pc(*s++); }
	inline void write(const string &s) { for ( char c : s ) pc(c); }
	template < class T, enable_if_t < _is_signed < T >, int > = 0 >
	inline void write(T x)
	{
		char buffer[numeric_limits < T >::digits10 + 1]; int digits = 0;
		if ( x >= 0 )  do buffer[digits++] =  ( x % 10 ) | 48, x /= 10; while ( x );
		else { pc(45); do buffer[digits++] = -( x % 10 ) | 48, x /= 10; while ( x ); }
		while ( digits ) pc(buffer[--digits]);
	}
	template < class T, enable_if_t < _is_unsigned < T >, int > = 0 >
	inline void write(T x)
	{
		char buffer[numeric_limits < T >::digits10]; int digits = 0;
		do buffer[digits++] = ( x % 10 ) | 48, x /= 10; while ( x );
		while ( digits ) pc(buffer[--digits]);
	}
	template < int N > struct _tuple_io_helper
	{
		template < class ...T > static inline void _read(tuple < T... > &x) { _tuple_io_helper < N - 1 >::_read(x), read(get<N - 1>(x)); }
		template < class ...T > static inline void _write(const tuple < T... > &x) { _tuple_io_helper < N - 1 >::_write(x), pc(32), write(get<N - 1>(x)); }
	};
	template <> struct _tuple_io_helper < 1 >
	{
		template < class ...T > static inline void _read(tuple < T... > &x) { read(get<0>(x)); }
		template < class ...T > static inline void _write(const tuple < T... > &x) { write(get<0>(x)); }
	};
	template < class ...T > inline void read(tuple < T... > &x) { _tuple_io_helper < sizeof...(T) >::_read(x); }
	template < class ...T > inline void write(const tuple < T... > &x) { _tuple_io_helper < sizeof...(T) >::_write(x); }
	template < class T1, class T2 > inline void read(pair < T1, T2 > &x) { read(x.first), read(x.second); }
	template < class T1, class T2 > inline void write(const pair < T1, T2 > &x) { write(x.first), pc(32), write(x.second); }
	template < class T1, class ...T2 > inline void read(T1 &x, T2 &...y) { read(x), read(y...); }
	template < class ...T > inline void read_cstr(char *x, T *...y) { read_cstr(x), read_cstr(y...); }
	template < class T1, class ...T2 > inline void write(const T1 &x, const T2 &...y) { write(x), write(y...); }
	template < class ...T > inline void write_cstr(const char *x, const T *...y) { write_cstr(x), write_cstr(y...); }
	template < class T > inline void print(const T &x) { write(x); }
	inline void print_cstr(const char *x) { write_cstr(x); }
	template < class T1, class ...T2 > inline void print(const T1 &x, const T2 &...y) { write(x), pc(32), print(y...); }
	template < class ...T > inline void print_cstr(const char *x, const T *...y) { write_cstr(x), pc(32), print_cstr(y...); }
	inline void println() { pc(10); } inline void println_cstr() { pc(10); }
	template < class ...T > inline void println(const T &...x) { print(x...), pc(10); }
	template < class ...T > inline void println_cstr(const T *...x) { print_cstr(x...), pc(10); }
}
using FastIO::read;using FastIO::read_cstr;using FastIO::write;using FastIO::write_cstr;using FastIO::println;using FastIO::println_cstr;
const int N=1e6+5,M=1e5+5,INF=1e9;
int n,m,cnt,Tc;LL ans;
int Tim,Dfn[M*4],vec[N][2],vnx[M][2];
int Ghd[N],Gnxt[N],dL[N],dR[N],sz[N],vs[N];
int f[N],fd[M];pair<int,int>E[M],nxt[M];
inline pair<int,int>operator+(const pair<int,int>&x,const int&y){return make_pair(x.first+y,x.second);}
inline pair<int,int>operator-(const pair<int,int>&x,const int&y){return make_pair(x.first-y,x.second);}
struct info{
    int mn,se,mnid,seid;
    info(){}
    info(const int&_):mn(INF),se(INF),mnid(-1),seid(-1){}
    inline void ins(const int&x,const int&y){if(y==mnid)mn=min(mn,x);else if(x<mn)se=mn,seid=mnid,mn=x,mnid=y;else if(x<se)se=x,seid=y;}
    inline pair<int,int>qmin(const int&x){return x==mnid?make_pair(se,seid):make_pair(mn,mnid);}
    inline void merge(const info&o){ins(o.mn,o.mnid),ins(o.se,o.seid);}
}T2[M*8],Vec[M*50],preX[M*2],sufX[M*2],preY[M*2],sufY[M*2];
int Cnt,Top,Stk[M*50],Nxt[M*50];
inline void Ins(int&x,int y){const int z=Top?Stk[Top--]:++Cnt;Nxt[z]=x,Vec[z]=Vec[y],x=z;}
struct Info{
    int hd;
    inline void ins(const int&x,const int&y){Ins(hd,hd);Vec[hd].ins(x,y);}
    inline pair<int,int>qmin(const int&x){return Vec[hd].qmin(x);}
    inline void del(){Stk[++Top]=hd,hd=Nxt[hd];}
}Tr[M*2],T0[M*8],T1[M*8];
int top,stk[M*8],Ls[M*8],Rs[M*8],rt[M*2];
int pre[N],pr[M*2],ls[M*2],rs[M*2],A[N],presz[N],son[N],lsz[N];
inline int find(const int&x){return fd[x]==x?x:fd[x]=find(fd[x]);}
inline void dfs0(int u){
    pre[u]=vs[u]?u:pre[f[u]];
    dL[u]=(vs[u]?++Tc:(Tc+1)),sz[u]=1,lsz[u]=(vs[u]?1:0),son[u]=0;
    for(int v=Ghd[u];v;v=Gnxt[v])
        dfs0(v),sz[u]+=sz[v],lsz[u]+=lsz[v],lsz[v]>lsz[son[u]]?son[u]=v:0;
    dR[u]=Tc;
}
inline void add0(int p,int l,int r,int x,int y,int z){
    T0[p].ins(y,z);
    if(l==r)return;
    const int mid=(l+r)>>1,ls=p*2,rs=p*2+1;
    x<=mid?add0(ls,l,mid,x,y,z):add0(rs,mid+1,r,x,y,z);
}
inline void del0(int p,int l,int r,int x){
    T0[p].del();
    if(l==r)return;
    const int mid=(l+r)>>1,ls=p*2,rs=p*2+1;
    x<=mid?del0(ls,l,mid,x):del0(rs,mid+1,r,x);
}
inline void add1(int p,int l,int r,int x,int y,int z){
    T1[p].ins(y,z);
    if(l==r)return;
    const int mid=(l+r)>>1,ls=p*2,rs=p*2+1;
    x<=mid?add1(ls,l,mid,x,y,z):add1(rs,mid+1,r,x,y,z);
}
inline void del1(int p,int l,int r,int x){
    T1[p].del();
    if(l==r)return;
    const int mid=(l+r)>>1,ls=p*2,rs=p*2+1;
    x<=mid?del1(ls,l,mid,x):del1(rs,mid+1,r,x);
}
inline void add_(int&p,int l,int r,int x,int y,int z){
    if(!p)T2[p=(top?stk[top--]:++cnt)]=info(1),Ls[p]=0,Rs[p]=0;
    T2[p].ins(y,z);
    if(l==r)return;
    const int mid=(l+r)>>1;
    x<=mid?add_(Ls[p],l,mid,x,y,z):add_(Rs[p],mid+1,r,x,y,z);
}
inline pair<int,int>qry0(int p,int l,int r,int x,int y,int z){
    if(x<=l&&r<=y)return T0[p].qmin(z);
    const int mid=(l+r)>>1,ls=p*2,rs=p*2+1;
    if(y<=mid)return qry0(ls,l,mid,x,y,z);
    if(x>mid)return qry0(rs,mid+1,r,x,y,z);
    return min(qry0(ls,l,mid,x,y,z),qry0(rs,mid+1,r,x,y,z));
}
inline pair<int,int>qry1(int p,int l,int r,int x,int y,int z){
    if(x<=l&&r<=y)return T1[p].qmin(z);
    const int mid=(l+r)>>1,ls=p*2,rs=p*2+1;
    if(y<=mid)return qry1(ls,l,mid,x,y,z);
    if(x>mid)return qry1(rs,mid+1,r,x,y,z);
    return min(qry1(ls,l,mid,x,y,z),qry1(rs,mid+1,r,x,y,z));
}
inline pair<int,int>qry_(int p,int l,int r,int x,int y,int z){
    if(!p)return make_pair(INF,-1);
    if(x<=l&&r<=y)return T2[p].qmin(z);
    const int mid=(l+r)>>1;
    if(y<=mid)return qry_(Ls[p],l,mid,x,y,z);
    if(x>mid)return qry_(Rs[p],mid+1,r,x,y,z);
    return min(qry_(Ls[p],l,mid,x,y,z),qry_(Rs[p],mid+1,r,x,y,z));
}
inline void merge(int&p,int q){
    if(!p||!q)return p|=q,void();
    merge(Ls[p],Ls[q]),merge(Rs[p],Rs[q]),T2[p].merge(T2[q]),stk[++top]=q;
}
inline int sbuild(int l,int r){
    const int p=lower_bound(presz+l,presz+r,(presz[l]+presz[r])/2)-presz,u=dL[A[p]];
    if(l<p)pr[ls[u]=sbuild(l,p-1)]=u;else ls[u]=0;
    if(p<r)pr[rs[u]=sbuild(p+1,r)]=u;else rs[u]=0;
    return u;
}
inline int build(int u){
    for(int i=u;i;i=son[i])
        for(int v=Ghd[i];v;v=Gnxt[v])if(v!=son[i])
            pr[build(v)]=dL[pre[i]];
    int m=0;
    for(int i=u;i;i=son[i])if(vs[i])
        A[++m]=i,presz[m]=presz[m-1]+lsz[i]-lsz[son[i]];
    return m?sbuild(1,m):0;
}
inline void ins(int u,int v,int w){
    for(int r=ls[u=dL[u]];;r=u,u=pr[u]){
        if(r==ls[u])Tr[u].ins(v,w);
        if(u!=ls[pr[u]]&&u!=rs[pr[u]])break;
    }
}
inline void del(int u){
    for(int r=ls[u=dL[u]];;r=u,u=pr[u]){
        if(r==ls[u])Tr[u].del();
        if(u!=ls[pr[u]]&&u!=rs[pr[u]])break;
    }
}
inline pair<int,int>qry(int u,int k){
    u=dL[u];
    pair<int,int>z(INF,-1);
    for(int r=-1;u;r=u,u=pr[u])if(r!=ls[u])z=min(z,Tr[u].qmin(k));
    return z;
}
inline void DfsOrder(int u){
    if(!lsz[u])return;
    if(vs[u])Dfn[++Tim]=u;
    if(son[u]){
        DfsOrder(son[u]);
        for(int v=Ghd[u];v;v=Gnxt[v])if(v!=son[u])
            DfsOrder(v);
    }
    if(vs[u])Dfn[++Tim]=-u;
}
signed main(){
    T2[0]=info(1),Vec[0]=info(1),preX[0]=info(1),preY[0]=info(1);
    cin.tie(0)->sync_with_stdio(0);
    read(n,m),vs[1]=1;
    for(int i=2;i<=n;++i)
        read(f[i]),Gnxt[i]=Ghd[f[i]],Ghd[f[i]]=i;
    for(int i=1;i<=m;++i)
        read(E[i]),fd[i]=i,vs[E[i].first]=vs[E[i].second]=1,
        vnx[i][0]=vec[E[i].first][0],vec[E[i].first][0]=i,
        vnx[i][1]=vec[E[i].second][1],vec[E[i].second][1]=i;
    dfs0(1),build(1),DfsOrder(1);
    for(;;){
        info cur(1);
        for(int i=1;i<=m;++i)
            cur.ins(sz[E[i].first]+sz[E[i].second],fd[i]),nxt[i]=make_pair(INF,-1);
        for(int i=1;i<=m;++i)
            nxt[fd[i]]=min(nxt[fd[i]],cur.qmin(fd[i])+sz[E[i].first]+sz[E[i].second]);
        cnt=0,top=0;
        for(int i=1;i<=Tc;++i)sufX[i]=info(1),sufY[i]=info(1),rt[i]=0;
        for(int t=1;t<=Tim;++t){
            int u=Dfn[t];
            if(u>0){
                preX[dL[u]]=preX[dL[pre[f[u]]]],preY[dL[u]]=preY[dL[pre[f[u]]]];
                for(int i=vec[u][0];i;i=vnx[i][0])
                    ins(E[i].second,sz[E[i].first]+sz[E[i].second],fd[i]),
                    preX[dL[u]].ins(sz[E[i].first]+sz[E[i].second],fd[i]),
                    add0(1,1,Tc,dL[E[i].second],sz[E[i].first]-sz[E[i].second],fd[i]);
                for(int i=vec[u][0];i;i=vnx[i][0])
                    nxt[fd[i]]=min(nxt[fd[i]],qry(E[i].second,fd[i])-sz[E[i].first]-sz[E[i].second]),
                    nxt[fd[i]]=min(nxt[fd[i]],preX[dL[u]].qmin(fd[i])-sz[E[i].first]+sz[E[i].second]),
                    nxt[fd[i]]=min(nxt[fd[i]],qry0(1,1,Tc,dL[E[i].second],dR[E[i].second],fd[i])-sz[E[i].first]+sz[E[i].second]);
                for(int i=vec[u][1];i;i=vnx[i][1])
                    preY[dL[u]].ins(sz[E[i].first]+sz[E[i].second],fd[i]),
                    add1(1,1,Tc,dL[E[i].first],-sz[E[i].first]+sz[E[i].second],fd[i]);
                for(int i=vec[u][1];i;i=vnx[i][1])
                    nxt[fd[i]]=min(nxt[fd[i]],preY[dL[u]].qmin(fd[i])+sz[E[i].first]-sz[E[i].second]),
                    nxt[fd[i]]=min(nxt[fd[i]],qry1(1,1,Tc,dL[E[i].first],dR[E[i].first],fd[i])+sz[E[i].first]-sz[E[i].second]);
            }
            else{
                u=-u;
                for(int i=vec[u][0];i;i=vnx[i][0])
                    del(E[i].second),
                    del0(1,1,Tc,dL[E[i].second]),
                    add_(rt[dL[u]],1,Tc,dL[E[i].second],-sz[E[i].first]-sz[E[i].second],fd[i]),
                    sufX[dL[u]].ins(-sz[E[i].first]+sz[E[i].second],fd[i]);
                for(int i=vec[u][0];i;i=vnx[i][0])
                    nxt[fd[i]]=min(nxt[fd[i]],qry_(rt[dL[u]],1,Tc,dL[E[i].second],dR[E[i].second],fd[i])+sz[E[i].first]+sz[E[i].second]),
                    nxt[fd[i]]=min(nxt[fd[i]],sufX[dL[u]].qmin(fd[i])+sz[E[i].first]+sz[E[i].second]);
                for(int i=vec[u][1];i;i=vnx[i][1])
                    del1(1,1,Tc,dL[E[i].first]),
                    sufY[dL[u]].ins(sz[E[i].first]-sz[E[i].second],fd[i]);
                for(int i=vec[u][1];i;i=vnx[i][1])
                    nxt[fd[i]]=min(nxt[fd[i]],sufY[dL[u]].qmin(fd[i])+sz[E[i].first]+sz[E[i].second]);
                if(pre[f[u]]){
                    merge(rt[dL[pre[f[u]]]],rt[dL[u]]);
                    sufX[dL[pre[f[u]]]].merge(sufX[dL[u]]);
                    sufY[dL[pre[f[u]]]].merge(sufY[dL[u]]);
                }
            }
        }
        for(int i=1;i<=m;++i)if(fd[i]==i){
            const auto&[w,j]=nxt[i];
            if(find(j)!=i)fd[i]=j,ans+=w;
        }
        bool ok=1;
        for(int i=1;i<=m;++i)ok&=find(i)==find(1);
        if(ok)break;
    }
    return println(ans),0;
}

Details

Subtask #1:

score: 10
Accepted

Test #1:

score: 10
Accepted
time: 5ms
memory: 4008kb

Test #2:

score: 10
Accepted
time: 5ms
memory: 4008kb

Test #3:

score: 10
Accepted
time: 2ms
memory: 3984kb

Test #4:

score: 10
Accepted
time: 5ms
memory: 3888kb

Test #5:

score: 10
Accepted
time: 5ms
memory: 3908kb

Subtask #2:

score: 10
Accepted

Dependency #1:

100%
Accepted

Test #6:

score: 10
Accepted
time: 259ms
memory: 64408kb

Test #7:

score: 10
Accepted
time: 247ms
memory: 63876kb

Test #8:

score: 10
Accepted
time: 143ms
memory: 61448kb

Test #9:

score: 10
Accepted
time: 146ms
memory: 62280kb

Test #10:

score: 10
Accepted
time: 244ms
memory: 63656kb

Subtask #3:

score: 10
Accepted

Dependency #2:

100%
Accepted

Test #11:

score: 10
Accepted
time: 726ms
memory: 73776kb

Test #12:

score: 10
Accepted
time: 493ms
memory: 73172kb

Test #13:

score: 10
Accepted
time: 377ms
memory: 70540kb

Test #14:

score: 10
Accepted
time: 361ms
memory: 71404kb

Test #15:

score: 10
Accepted
time: 483ms
memory: 72872kb

Subtask #4:

score: 20
Accepted

Test #16:

score: 20
Accepted
time: 298ms
memory: 9268kb

Test #17:

score: 20
Accepted
time: 364ms
memory: 10084kb

Test #18:

score: 20
Accepted
time: 256ms
memory: 8656kb

Test #19:

score: 20
Accepted
time: 267ms
memory: 8996kb

Test #20:

score: 20
Accepted
time: 352ms
memory: 9160kb

Subtask #5:

score: 10
Accepted

Test #21:

score: 10
Accepted
time: 2959ms
memory: 250812kb

Test #22:

score: 10
Accepted
time: 2945ms
memory: 250800kb

Test #23:

score: 10
Accepted
time: 2922ms
memory: 250868kb

Test #24:

score: 10
Accepted
time: 2949ms
memory: 250752kb

Test #25:

score: 10
Accepted
time: 2921ms
memory: 250748kb

Subtask #6:

score: 10
Accepted

Test #26:

score: 10
Accepted
time: 607ms
memory: 79080kb

Test #27:

score: 10
Accepted
time: 612ms
memory: 79060kb

Test #28:

score: 10
Accepted
time: 601ms
memory: 79144kb

Test #29:

score: 10
Accepted
time: 630ms
memory: 78984kb

Test #30:

score: 10
Accepted
time: 614ms
memory: 79012kb

Subtask #7:

score: 30
Accepted

Dependency #1:

100%
Accepted

Dependency #2:

100%
Accepted

Dependency #3:

100%
Accepted

Dependency #4:

100%
Accepted

Dependency #5:

100%
Accepted

Dependency #6:

100%
Accepted

Test #31:

score: 30
Accepted
time: 1594ms
memory: 88680kb

Test #32:

score: 30
Accepted
time: 931ms
memory: 90340kb

Test #33:

score: 30
Accepted
time: 718ms
memory: 85164kb

Test #34:

score: 30
Accepted
time: 764ms
memory: 86024kb

Test #35:

score: 30
Accepted
time: 919ms
memory: 89916kb

Test #36:

score: 30
Accepted
time: 1665ms
memory: 89188kb

Test #37:

score: 30
Accepted
time: 971ms
memory: 89500kb

Test #38:

score: 30
Accepted
time: 730ms
memory: 85156kb

Test #39:

score: 30
Accepted
time: 730ms
memory: 86144kb

Test #40:

score: 30
Accepted
time: 908ms
memory: 87672kb