ゲーム上のCTYZツリー(P5557トラベル/ P5558ハート秋/ P5559は、日守備の星の街を失いました)

概要

ミッド影響により、ゲーム時間内で切断しませんでした\(T3 \)

難易度を考え\(TL <T2 <T3 \) コード難易\(T1> T2> T3 \ )

P5557トラベル

明らかにジャンプリングアップダイレクトモードを、そう何度も経験した後、再びリング上の各点かどうかを見つけるために

リング上のリングに決定されるように、\(LEN \)ループ長に移動する必要はないと判断、\(LEN \) プレ歩行の各点\(2 ^ iは\)位置

\(T1 ^ T2の\)大きすぎる、直接決定することができないパワーの急速な決意で得られるよりも大きい\(LEN \)

  • 最初のレコードよりも大きい場合、他のリングに来て、リングヘッダのリングの落下距離上の最終位置\(X \当量T1 ^ T2 -len(MOD〜LEN)\)

  • 数よりも少ない説明は直接行くこと倍増し、大きさではありません

#include<bits/stdc++.h>
typedef long long LL;
const LL maxn=400009;
inline LL Read(){
    LL x(0),f(1); char c=getchar();
    while(c<'0' || c>'9'){
        if(c=='-') f=-1; c=getchar();
    }
    while(c>='0' && c<='9'){
        x=(x<<3ll)+(x<<1ll)+c-'0'; c=getchar();
    }return x*f;
}
LL n,m,top,tim;
LL a[maxn],f[maxn][21],seed[21],visit[maxn],len[maxn],sta[maxn],dep[maxn],Len[maxn],dfn[maxn];
inline LL Pow(LL base,LL b,LL mod){
    LL ret(1);
    while(b){
        if(b&1) ret=1ll*ret*base%mod;
        base=1ll*base*base%mod; b>>=1;
    }return ret;
}
void Dfs1(LL u){
    sta[++top]=u; dfn[u]=++tim;
    LL v(a[u]);
    visit[u]=1;
    if(visit[v] && !Len[v]){
        len[u]=dep[u]-dep[v]+1;
        LL now;
        do{
            now=sta[top--]; len[now]=len[u]; visit[now]=false;
        }while(now!=v);
        return;
    }
    dep[v]=dep[u]+1;
    if(!dfn[v]) Dfs1(v);
    if(!len[u]){
        Len[u]=Len[v]+1;
    }
}
int main(){
    n=Read();
    for(LL i=1;i<=n;++i) a[i]=Read(),f[i][0]=a[i];
    for(LL i=1;i<=n;++i){
        if(!dfn[i]) dep[i]=0,Dfs1(i);
    }
    for(LL j=1;j<=20;++j)
        for(LL i=1;i<=n;++i)
            f[i][j]=f[f[i][j-1]][j-1];
    seed[0]=1;
    for(LL i=1;i<=20;++i) seed[i]=seed[i-1]*2;
    m=Read();
    while(m--){
        LL s(Read()),t1(Read()),t2(Read()),now1(s);
        if(Len[s]){
            LL base(t1),b(t2),R(1),flag(0),tmp(Len[s]);
            while(b){
                if(b&1){
                    R=R*base;
                    if(R>tmp){
                        flag=true; break;
                    }
                } base=base*base;
                if(b!=1){
                    if(base>tmp){
                        flag=1; break;
                    }
                }
                b>>=1;
            }
            if(!flag){
                tmp=R;
                for(LL i=20;i>=0;--i){
                    if(tmp>=seed[i]){
                        tmp-=seed[i]; now1=f[now1][i];
                    }
                    if(!tmp){
                        printf("%lld\n",now1); break;
                    }
                }
                continue;
            }else{
                for(LL i=20;i>=0;--i){
                    if(tmp>=seed[i]){
                        tmp-=seed[i]; now1=f[now1][i];
                    }
                }
            }
        }
        LL ret,now(now1);
        ret=(Pow(t1,t2,len[now])-Len[s]%len[now]+len[now])%len[now];、
        if(!ret){
            printf("%lld\n",now); continue;
        }
        for(LL j=20;j>=0;--j){
            if(ret>=seed[j])
                ret-=seed[j],now=f[now][j];
            if(!ret){
                printf("%lld\n",now); break;
            }
        }
    }
    return 0;
}

P5558ハート秋

見出さ側が正と一定の色よりも小さい\(5 \) 決定(inc_ {I、J、\を C1、C2}、low_ {I、J、C1、C2} \) されている(私は\)\する\ (Iは\)\(2 ^ j個の\)レベル祖先シーケンスヘッダ\(C1 \)テール\(C2 \)単調増加/減少、最長の長さ- 、

各クエリについては、(X-LCAの\)\する(INC \)\するために、一緒に(Y-LCAの\)を\する(\低い)\一緒にし、その後で\(DP \)もう一度

\(O(5 ^ 4(N-Qの+)logN個)\) 転送からの時間\(^ 5 4 \)カードの不満は、それが遅い実行されません。

#include<bits/stdc++.h>
typedef int LL;
const LL maxn=30009;
inline LL Read(){
    LL x(0),f(1); char c=getchar();
    while(c<'0' || c>'9'){
        if(c=='-') f=-1; c=getchar();
    }
    while(c>='0' && c<='9'){
        x=(x<<3ll)+(x<<1ll)+c-'0'; c=getchar();
    }return x*f;
}
struct node{
    LL to,nxt,w;
}dis[maxn<<1];
LL n,m,num;
LL head[maxn],f1[6][6],f2[6][6],inc[maxn][16][6][6],low[maxn][16][6][6],F[maxn][16],dep[maxn],tmp[6][6];
inline void Add(LL u,LL v,LL w){
    dis[++num]=(node){v,head[u],w}; head[u]=num;
}
void Dfs(LL u,LL f,LL c){
    if(u!=1){
        inc[u][0][c][c]=1; low[u][0][c][c]=1;
        F[u][0]=f; for(LL i=1;i<=15;++i) F[u][i]=F[F[u][i-1]][i-1];
        for(LL i=1;i<=15;++i){
            for(LL j=1;j<=5;++j)
                for(LL k=j;k<=5;++k)
                    for(LL jj=j;jj<=k;++jj)
                        for(LL kk=jj;kk<=k;++kk)
                            inc[u][i][j][k]=std::max(inc[u][i][j][k],inc[u][i-1][j][jj]+inc[F[u][i-1]][i-1][kk][k]);
        }
        for(LL i=1;i<=15;++i){
            for(LL j=1;j<=5;++j)
                for(LL k=1;k<=j;++k)
                    for(LL jj=k;jj<=j;++jj)
                        for(LL kk=k;kk<=jj;++kk)
                            low[u][i][j][k]=std::max(low[u][i][j][k],low[u][i-1][j][jj]+low[F[u][i-1]][i-1][kk][k]);
        }
    }
    for(LL i=head[u];i;i=dis[i].nxt){
        LL v(dis[i].to);
        if(v==f) continue;
        dep[v]=dep[u]+1;
        Dfs(v,u,dis[i].w);
    }
}
inline LL Lca(LL u,LL v){
    if(dep[u]<dep[v]) std::swap(u,v);
    for(LL i=15;i>=0;--i)
        if(dep[F[u][i]]>=dep[v]) u=F[u][i];
    if(u==v) return u;
    for(LL i=15;i>=0;--i)
        if(F[u][i]!=F[v][i]) u=F[u][i],v=F[v][i];
    return F[u][0];
}
inline void Solve1(LL u,LL f){
    memset(f1,0,sizeof(f1));
    LL ret(dep[u]-dep[f]);
    for(LL i=15;i>=0;--i){
        if((ret&(1<<i))==(1<<i)){
            memcpy(tmp,f1,sizeof(f1));
            memset(f1,0,sizeof(f1));
            for(LL j=1;j<=5;++j)
                for(LL k=j;k<=5;++k)
                    for(LL jj=j;jj<=k;++jj)
                        for(LL kk=jj;kk<=k;++kk)
                            f1[j][k]=std::max(f1[j][k],tmp[j][jj]+inc[u][i][kk][k]);
            u=F[u][i];
        }
    }
}
inline void Solve2(LL u,LL f){
    memset(f2,0,sizeof(f2));
    LL ret(dep[u]-dep[f]);
    for(LL i=15;i>=0;--i){
        if((ret&(1<<i))==(1<<i)){
            memcpy(tmp,f2,sizeof(f2));
            memset(f2,0,sizeof(f2));
            for(LL j=1;j<=5;++j)
                for(LL k=1;k<=j;++k)
                    for(LL jj=k;jj<=j;++jj)
                        for(LL kk=k;kk<=jj;++kk)
                            f2[j][k]=std::max(f2[j][k],tmp[j][jj]+low[u][i][kk][k]);
            u=F[u][i];
        }
    }
}
int main(){
    n=Read();
    for(LL i=1;i<n;++i){
        LL u(Read()),v(Read()),w(Read());
        Add(u,v,w); Add(v,u,w);
    }
    Dfs(1,0,0);
    m=Read();
    while(m--){
        LL u(Read()),v(Read());
        LL lca(Lca(u,v));
        Solve1(u,lca); Solve2(v,lca);
        LL ans(0);
        for(LL i=1;i<=5;++i)
            for(LL j=i;j<=5;++j)
                for(LL ii=i;ii<=j;++ii)
                    for(LL jj=ii;jj<=j;++jj)
                        ans=std::max(ans,f1[i][ii]+f2[j][jj]);
        printf("%d\n",ans);
    }
    return 0;
}

P5559は、その日、市内の守備の星を失いました

問題の意味:木が右側にあり、右の開始点です\(1 \) 毎回トランス/与えられたポイントの少し右に取って\((U、V)\ ) チェーン内の各ポイントのために必要とそのへ

おすすめ

転載: www.cnblogs.com/y2823774827y/p/11518248.html