2019年7月26日(数学、DP)

不快な、ゼロを爆破!

ねえ......タイトルバー

prob1:

タイトル効果:二つの操作:進数または排他的または数字のセットにロールオーバーへの1つ、とから求め\(S \)のように変更される(T \)\ステップの最小数を

\(SB \)の質問、完全に水の問題、結果\(BFS \)キュー・ライト・萎凋病の

最初の動作は、第二に変換することができ、それぞれの最大数は、唯一のXORを介してである\(BFS \)それいじり。しかし、最小チームの時に更新されるステップの数、および条件としてチームを更新するかどうか、そうでなければ、彼らはされます\(T、RE \)は、(私が知っているか聞いていない)爆破します

コードを貼り付けます。

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define in read()
#define fur(i,a,b) for(int i=a;i<=b;++i)
#define int long long
#define xx 270000
const int mod=998244353;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    for(;!isalnum(ch);ch=getchar()) if(ch=='-') f=-1;
    for(;isalnum(ch);ch=getchar()) x=x*10+ch-'0';
    return x*f;
}
int que[xx][3];
int q[xx],all,ans[xx];
inline void bfs()
{
    int head=0,tail=-1;
    que[++tail][0]=0;
    que[tail][1]=0;
    que[tail][2]=0;
    while(head<=tail)
    {
        int w=que[head][0],u=que[head][1],v=que[head++][2];
        fur(i,w+1,all)
        {
            if(!ans[u^q[i]])
            {
                que[++tail][0]=i;
                que[tail][1]=u^q[i];
                ans[u^q[i]]=v+1;
                que[tail][2]=v+1;
            }
        }
    }
}
signed main()
{
    int t=in;
    q[1]=1;
    fur(i,2,18) q[i]=q[i-1]<<1;
    while(t--)
    {
        int n=in,m=in;all=18;
        fur(i,1,n) q[++all]=in;
        int res=0;
        memset(ans,0,sizeof(ans));
        bfs();
        ans[0]=0;
        fur(i,1,m)
        {
            int s=in,tt=in;
            res=(res+i*ans[s^tt]%mod)%mod;
        }
        printf("%lld\n",res);
    }
    return 0;
}

prob2:B

タイトル効果:指定された文字列の文字列(英語のみ26文字がある)、最短辞書順最小のシーケンス列nonsubtyped

それはトピックマップ、どのように貪欲+のの無い考えだと思ったそして、それは文字列のタイトルだと思いました\(DP \)文字列のサイズが26未満であるとき、あなたは明らかに、このの性質によって、答えを得ることができ、タイトル(姉妹冷酷なああ)バックから\(DP \)

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define in read()
#define fur(i,a,b) for(int i=a;i<=b;++i)
#define fdr(i,a,b) for(int i=a;i>=b;--i)
#define xx 500010
#define inf 0x7fffffff
int f[xx][27],g[xx],pos[xx],n;
char ch[xx];
inline void dfs(int q,int len)
{
    if(len==1)
    {
        fur(i,1,26)
        {
            if(f[q][i]==n+1)
            {
                printf("%c",i+'a'-1);
                return;
            }
        }
    }
    fur(i,1,26)
    {
        if(g[f[q][i]]==len)
        {
            printf("%c",i+'a'-1);
            dfs(f[q][i]+1,len-1);
            break;
        }
    }
}
int main()
{
    scanf("%s",ch+1);
    n=strlen(ch+1);
    fur(i,1,26) f[n+1][i]=n+1,pos[i]=n+1;
    g[n+1]=1;
    fdr(i,n,1)
    {
        fur(j,1,26) f[i][j]=f[i+1][j];
        f[i][ch[i]-'a'+1]=i;
        g[i]=inf;
        fur(j,1,26) g[i]=min(g[i],g[pos[j]]+1);
        pos[ch[i]-'a'+1]=i;
    }
    int ans=inf;
    fur(i,1,26)
    {
        if(f[1][i]==n+1)
        {
            printf("%c\n",i+'a'-1);
            return 0;
        }
        ans=min(ans,g[f[1][i]]);
    }
    dfs(1,ans);
    printf("\n");
    return 0;
}

PRB3:C

タイトル効果:指定された\(N * m個の\)行列、プログラム番号の三点が同一直線上にあります

間違った式試験を押して、私は何も言う必要はありません

#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;
#define in read()
#define fur(i,a,b) for(int i=a;i<=b;++i)
#define int long long
const int xx=1e7+10;
const int n6=166666668;
const int mod=1e9+7;
int phi[xx],prime[xx],cnt=0,ans=0,m,n;
bool mark[xx];
inline void handle()
{
    phi[1]=1;
    fur(i,2,n)
    {
        if(!mark[i]) phi[i]=i-1,prime[++cnt]=i;
        for(int j=1;j<=cnt&&prime[j]*i<=n;++j)
        {
            mark[i*prime[j]]=true;
            if(i%prime[j]) phi[i*prime[j]]=phi[i]*(prime[j]-1);
            else
            {
                phi[i*prime[j]]=phi[i]*prime[j];
                break;
            }
        }
    }
}
inline int calc(int x,int d,int u){return (x-u*d+x-d)*u/2%mod;}
inline int C(int nm){return nm*(nm-1)%mod*(nm-2)%mod*n6%mod;}
signed main()
{
    scanf("%lld%lld",&n,&m);
    if(n>m) swap(n,m);
    --n;--m;
    handle();
    fur(i,1,n)
    {
        int tmp=phi[i];
        tmp=(tmp*calc(n+1,i,n/i))%mod;
        tmp=(tmp*calc(m+1,i,m/i))%mod;
        ans=(ans+tmp)%mod;
    }
    ans=(ans-((n+1)*n/2%mod)*((m+1)*m/2%mod)%mod+mod)%mod;
    ans=(ans<<1)%mod;
    ans=(ans+(n+1)*C(m+1)%mod+(m+1)*C(n+1)%mod)%mod;
    printf("%lld\n",ans);
    return 0;
}

prob4:D

タイトル効果:指定された\(N- \)二つのノードからなる図中の任意の参照符号、図番号に木の存在を見つける\(K \)番目と

ナレッジベース:スターリング+ pruferの第2カテゴリーのシーケンス番号

そして、クラス悪い気分、慎重に聞いていない、それはこの問題は発生しません、標準プロセスが理解していなかった、直接\(kuai \)姉妹\(STDの\は)それを忘れてください。

(嫌なこのライン圧):

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
#define LL long long
#define N 50005
using namespace std;

const int mo=998244353,G=3;
int n,K,rev[N*3],len,num,g[25][N];
LL S[25][25],jc[N],ny[N],wn[50],f[N*3],h[N*3],ans;

LL qp(LL x,LL y) {
    LL res=1;
    for(;y;y>>=1ll,x=x*x%mo)
        if(y&1ll) res=res*x%mo;
    return res;
}
void pre() {
    jc[0]=ny[0]=1;
    for(int i=1;i<=n;++i) jc[i]=jc[i-1]*i%mo;
    ny[n]=qp(jc[n],mo-2);
    for(int i=n-1;i>=0;--i) ny[i]=ny[i+1]*(i+1)%mo;
    f[1]=1*ny[0];
    for(int i=2;i<=n;++i) f[i]=qp(i,i-2)*ny[i-1]%mo;
    S[0][0]=1;
    for(int i=1;i<=K;++i)
        for(int j=1;j<=i;++j)
            S[i][j]=(S[i-1][j]*j%mo+S[i-1][j-1])%mo;
    for(len=1,num=0;len<=n+n;len<<=1,num++);
    for(int i=1;i<len;++i) rev[i]=(rev[i>>1]>>1)|((i&1)<<(num-1));
    for(int i=0;i<=45;++i) wn[i]=qp(G,(mo-1)/(1<<i));
}
void ntt(LL *x,int sign) {
    for(int i=0;i<len;++i) if(i<rev[i]) swap(x[i],x[rev[i]]);
    for(int k=2,e=1;k<=len;k<<=1,e++) {
        for(int i=0;i<len;i+=k) {
            LL *a=x+i,*b=x+i+(k>>1); LL u,v,w=1;
            for(int j=0;j<(k>>1);++j,w=w*wn[e]%mo) {
                u=a[j],v=b[j]*w%mo;
                a[j]=u+v; a[j]>=mo?a[j]-=mo:0;
                b[j]=u-v; b[j]<0?b[j]+=mo:0;
            }
        }
    }
    if(sign==-1) {
        int inv=qp(len,mo-2);
        for(int i=0;i<len;++i) x[i]=x[i]*inv%mo;
        reverse(x+1,x+len);
    }
}
LL C(LL x,LL y) {return x>=y?jc[x]*ny[y]%mo*ny[x-y]%mo:0;}
int main()
{
    scanf("%d%d",&n,&K);
    pre();
    g[0][0]=1; ntt(f,1);
    for(int i=1;i<=K;++i) {
        memset(h,0,sizeof(h[0])*len);
        for(int j=0;j<=n;++j) h[j]=1ll*g[i-1][j]*ny[j]%mo;
        ntt(h,1);
        for(int j=0;j<len;++j) h[j]=h[j]*f[j]%mo;
        ntt(h,-1);
        for(int j=1;j<=n;++j) g[i][j]=h[j]*jc[j-1]%mo;
    }
    for(int i=1;i<=n;++i) {
        LL tmp=qp(2,1ll*(n-i)*(n-i-1)/2ll)*C(n,i)%mo;
        for(int j=1;j<=K;++j) {
            ans+=g[j][i]*S[K][j]%mo*jc[j]%mo*tmp%mo;     //!!!!!
            ans>=mo?ans-=mo:0;
        }
    }
    printf("%lld\n",ans);
    return 0;
}

おすすめ

転載: www.cnblogs.com/ALANALLEN21LOVE28/p/11312991.html