noi.ac NOIチャレンジキャンプシミュレーションゲーム1-5

注意:ブロガーは、鶏肉の料理のすべてのテスト爆発底ゼロであるので、このブログにGUGU区にありそうであるように、

(私はそれをしない場合、私はqwqwqを責めることはできない......コードは、問題の解決策を書き込まないだけでACペースト指します)


1日目

T1スワップ

  • 23ptsはその後、我々は状態を一度だけアクセスされることを保証するために、ハッシュの状態を見て、状態からの検索を開始バースト。時間複雑\(O(N-!n-は)\) 複雑な気持ちは55分、問題なく過ごしたが、戻っREになります.......私にはわからない、なぜああQAQ
  • 55ptsは、その後、我々は、相対位置決定端状態の正当性(相対的位置を指すを交換しなかったN人よりも大きな幅を決定することにより、2つの各々を見て、この後者の構成で列挙もしまだ以下POS_Xより後に元POS_X <POS_Y、 POS_Y)。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#define MAXN 100010
using namespace std;
int n,m,tot,ans;
int a[MAXN],pos[MAXN];
struct Line{int u,v;}line[MAXN<<1];
inline bool check()
{
    for(int i=1;i<=tot;i++)
        if(pos[line[i].u]>pos[line[i].v]) return false;
    return true;
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    #endif
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    for(int i=1;i<=n;i++)
        for(int j=i+1;j<=n;j++)
            if(a[i]+a[j]>m)
                line[++tot]=(Line){i,j};
    for(int i=1;i<=n;i++) pos[i]=i;
    do{
        if(check()==true) ans++;
    }while(next_permutation(&pos[1],&pos[n+1]));
    printf("%d\n",ans);
    return 0;
}

我々は大に小型に対処するもの、練習の外に神々を比較してください。現在の最小数のために、我々はそれを判断し、現在の最大数は、交換することはできません。
それと最大の交換は、それとカラム内のすべての数字の現在の数が現在の数が順番にあり、最後の位置を意味する(切り替えることができる場合番号- > N種)ので、我々はn倍の答えを与えることができ、その後、一連の再帰的計算の残りのために、最小数を削除する(これは状況は、nに方法の最小数に挿入することができるものであるかどうか、最終シーケンス理由それらの間で)答えを構成し、
そうでないと最大の交換、数のいずれかの最大を交換することはできませんし、現在のシーケンスならば、それは無用である、とだけ、現在の位置での我々はそれを削除貢献の種類、再帰的な処理シーケンスができます。

  • 100pts
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
#include<algorithm>
#define MAXN 100010
#define mod 1000000007
using namespace std;
int n,m;
int a[MAXN];
vector<int>vec;
inline int solve(vector<int>x)
{
//  for(int i=0;i<x.size();i++) printf("%d ",x[i]); puts("");
    if(x.size()<=1) return 1;
    int min_pos,max_pos,minn=0x3f3f3f3f,maxx=-0x3f3f3f3f;
    for(int i=0;i<x.size();i++) 
        if(x[i]<minn)
            minn=x[i],min_pos=i;
    for(int i=0;i<x.size();i++)
        if(x[i]>maxx)
            maxx=x[i],max_pos=i;
//  printf("max_pos=%d min_pos=%d\n",max_pos,min_pos);
    if(x[min_pos]+x[max_pos]>m)
    {
        vector<int>cur1,cur2;
        cur1.clear(),cur2.clear();
        for(int i=0;i<max_pos;i++) cur1.push_back(x[i]);
        for(int i=max_pos+1;i<x.size();i++) cur2.push_back(x[i]);
        int cur_ans1=solve(cur1);
        int cur_ans2=solve(cur2);
        return 1ll*cur_ans1*cur_ans2%mod;
    }
    vector<int>cur;
    cur.clear();
    for(int i=0;i<min_pos;i++) cur.push_back(x[i]);
    for(int i=min_pos+1;i<x.size();i++) cur.push_back(x[i]);
    return 1ll*solve(cur)*x.size()%mod;
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    #endif
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++) scanf("%d",&a[i]),vec.push_back(a[i]);
    if(n==1) {printf("1\n");return 0;}
    printf("%d\n",solve(vec));
    return 0;
}

T2ステート

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define MAXN 75
#define mod 1000000007
using namespace std;
int n,k;
int a[MAXN],b[MAXN];
inline void print(int *x)
{
    for(int i=1;i<=n;i++) printf("%d ",x[i]);
    puts("");
}

namespace subtask1
{
    inline void solve()
    {
        int ans=0;
        for(int i=1;i<=n;i++) a[i]=b[i]=i;
        do
        {
            do
            {
                int cur_ans=0;
                for(int i=1;i<=n;i++) cur_ans+=max(a[i],b[i]);
                if(cur_ans>=k) ans++;
            }while(next_permutation(&b[1],&b[n+1]));
        }while(next_permutation(&a[1],&a[n+1]));
        printf("%d\n",ans);
    }
}

namespace subtask2
{
    long long ans=0;
    int tmp[MAXN],done[MAXN];
    inline void search(int x)
    {
        if(x>n)
        {
            long long sum=0;
            for(int i=1;i<=n;i++) sum+=max(tmp[i],i);
            if(sum>=k) ans++;
            return; 
        }   
        for(int i=1;i<=n;i++)
        {
            if(done[i]) continue;
            tmp[x]=i,done[i]=1;
            search(x+1);
            tmp[x]=0,done[i]=0;
        }
    }
    inline void solve()
    {
        for(int i=1;i<=n;i++) done[i]=0;
        search(1);
        for(int i=1;i<=n;i++)
            ans=1ll*ans*i%mod;
        printf("%lld\n",ans);
    }
}

namespace subtask3
{
    long long ans;
    long long f[80][80][5010];
    inline void solve()
    {
        f[0][0][0]=1;
        for(int i=1;i<=n;++i)
            for(int j=0;j<i;++j)
                for(int k=0;k<=4901;++k)
                    if(f[i-1][j][k])
                    {
                        f[i][j+1][k+i]=(f[i][j+1][k+i]+f[i-1][j][k])%mod;
                        f[i][j+2][k+2*i]=(f[i][j+2][k+2*i]+f[i-1][j][k]*(i-1-j)*(i-1-j))%mod;
                        f[i][j+1][k+i]=(f[i][j+1][k+i]+2*f[i-1][j][k]*(i-1-j))%mod;
                        f[i][j][k]=(f[i][j][k]+f[i-1][j][k])%mod;
                    }
        for(int i=k;i<=4901;++i)
            ans=(ans+f[n][n][i])%mod;
        for(int i=1;i<=n;++i)
            ans=(ans*i)%mod;
        printf("%lld",ans);
    }
}

using namespace subtask1;
using namespace subtask2;
using namespace subtask3;

int main()
{
    #ifndef ONLINE_JUDGE
    freopen("ce2.in","r",stdin);
    #endif
    scanf("%d%d",&n,&k);
    if(n<=5) subtask1::solve();
    else if(n<=10) subtask2::solve();
    else subtask3::solve();
    return 0;
}

T3シーケンス


2日目

T1の赤ちゃん

#include<algorithm>
#include<cstdio>
#include<cstring>
#define N 550000
#define M 100005
using namespace std;
int a[N][4],b[5]={-1,0,1,0,-1},d[M],e[M],f[M],g[M],h[M],i,j,l,m,n,o[N<<2],p[N<<2],q,s[N<<3],t,z;char c[N];bool w[N][4];
inline void add(int u){while(u<=t<<1)s[u]++,u+=u&-u;}
inline void del(int u){while(u<=t<<1)s[u]--,u+=u&-u;}
inline bool cmp(int u,int v){return a[d[u]][f[u]]<a[d[v]][f[v]];}
void dfs(int u,int v)
{
    ++v%=4;
    while(!w[u][v])(v+=3)%=4;
    if(a[u][v]<=t)return;
    a[u][v]=++t,o[t]=u,p[t]=v;
    dfs(u+m*b[v]+b[v+1],v);
}
inline int sum(int u)
{
    int v=0;
    while(u)v+=s[u],u-=u&-u;
    return v;
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    #endif
    scanf("%d%d%d%*s",&n,&m,&q),memset(a,0x7f,sizeof a);
    for(i=1;i<=n;i++)
    {
        for(scanf("%s",c),j=1;j<m;j++)if(c[j<<1]=='.')w[(i-1)*m+j][1]=w[(i-1)*m+j+1][3]=true;
        for(scanf("%s",c+1),j=1;j<=m;j++)if(c[j<<1]=='.')w[(i-1)*m+j][2]=w[i*m+j][0]=true;
    }
    for(i=0;i<q;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y),d[i]=(x-1)*m+y;
        scanf("%d%d",&x,&y),e[i]=(x-1)*m+y;
        scanf("%s",c),g[i]=i;
        if(*c=='U')f[i]=0;
        else if(*c=='R')f[i]=1;
        else if(*c=='D')f[i]=2;
        else if(*c=='L')f[i]=3;
        while(!w[d[i]][f[i]])(f[i]+=3)%=4;
    }
    for(dfs(1,0),i=1;i<=n*m;i++)add(min(min(a[i][0],a[i][1]),min(a[i][2],a[i][3])));
    for(sort(g,g+q,cmp),i=1,j=0;j<q;)
    {
        while(i<=t&&a[d[g[j]]][f[g[j]]]>i)
        del(i),a[o[i]][p[i]]+=t,add(min(min(a[o[i]][0],a[o[i]][1]),min(a[o[i]][2],a[o[i]][3]))),i++;
        while(j<q&&a[d[g[j]]][f[g[j]]]==i)
        h[g[j]]=sum(min(min(a[e[g[j]]][0],a[e[g[j]]][1]),min(a[e[g[j]]][2],a[e[g[j]]][3]))),j++;
    }
    for(i=0;i<q;i++)printf("%d\n",h[i]);
    return 0;
}

T2バイク

T3ブーム


3日目

T1シーケンス

フェアリーファックqwq

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#define MAXN 100010
using namespace std;
int n,m,q,tot,K,base,mod;
int a[MAXN],rt[MAXN];
bool done[MAXN];
struct Node{int v,ls,rs;}t[MAXN<<5];
struct Node2{int r_pos,hash;};
vector<int>pos[MAXN];//pos[a]表示a值的位置
inline void insert(int &x,int f,int l,int r,int k)
{
    x=++tot;
    t[x]=t[f],t[x].v++;
    if(l==r) return;
    int mid=(l+r)>>1;
    if(k<=mid) insert(t[x].ls,t[f].ls,l,mid,k);
    else insert(t[x].rs,t[f].rs,mid+1,r,k);
}
inline int query(int x,int l,int r,int k)
{
    if(k>t[x].v||k==0) return -1;
    if(l==r) return l;
    int mid=(l+r)>>1;
    if(k<=t[t[x].ls].v) return query(t[x].ls,l,mid,k);
    else return query(t[x].rs,mid+1,r,k-t[t[x].ls].v);
}
inline void solve(vector<Node2>&x)
{
    for(int now=1;now<=n;now++)
    {
        vector<Node2>nxt;
        int minn=query(rt[x[0].r_pos+1],1,MAXN-10,now);
        // cout<<"minn="<<minn<<endl;
        if(minn==-1) return;
        int st=0;
        for(st=pos[minn].size()-1;st>=0;st--)
            {if(pos[minn][st]<=x[0].r_pos) break;}
        // cout<<"st="<<st<<endl;
        if(st+1==(int)pos[minn].size()) continue;
        for(int i=st+1;i<pos[minn].size();i++)//枚举之后能接哪些位置
        {
            for(int j=0;j<x.size()&&x[j].r_pos<pos[minn][i];j++)//枚举前面从哪个位置来接新数
            {
                int hash=(1ll*x[j].hash*base+minn)%mod;
                printf("%d\n",hash);
                // printf("K=%d\n",K);
                K--;
                if(K<=0) return;
                nxt.push_back((Node2){pos[minn][i],hash});
            }
            if(K<=0) return;
        }
        // for(int i=0;i<nxt.size();i++) cout<<nxt[i].r_pos<<" "; cout<<endl;
        solve(nxt);
        if(K<=0) return;
    }
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    #endif
    scanf("%d%d%d%d",&n,&K,&base,&mod);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]),pos[a[i]].push_back(i);
    for(int i=n;i>=0;i--) 
    {
        if(done[a[i]]==0) 
            done[a[i]]=1,insert(rt[i],rt[i+1],1,MAXN-10,a[i]);
        else rt[i]=rt[i+1];
    }
    // for(int i=1;i<=n;i++) printf("rt[%d]=%d\n",i,rt[i]); 
    vector<Node2>cur;
    cur.push_back((Node2){0,0});
    solve(cur);
    return 0;
}

T2ゲーム

コードはEmacsのインデントポットで書かれている......そうqwqwq

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<vector>
#define MAXN 300010
#define mod 1000000007
using namespace std;
int n,A,B,ans1,ans2,t;
int ans[MAXN],ffa[MAXN],b[MAXN],g[MAXN],c[MAXN];
int head[MAXN],dis[MAXN],fa[MAXN],pref[MAXN],suf[MAXN];
struct Edge{int nxt,to;}edge[MAXN<<1];
inline bool cmp(int x,int y){return ans[x]>ans[y];}
inline void add(int from,int to)
{
    edge[++t].nxt=head[from],edge[t].to=to;
    head[from]=t;
}
inline void dfs1(int x,int pre,int ban)
{
    ans[x]=0;
    for(int i=head[x];i;i=edge[i].nxt)
    {
    int v=edge[i].to;
    if(v==pre||v==ban) continue;
    dfs1(v,x,ban);
    }
    int cur=0;
    for(int i=head[x];i;i=edge[i].nxt)
    {
    int v=edge[i].to;
    if(v==pre||v==ban) continue;
    b[++cur]=v;
    }
    sort(&b[1],&b[cur+1],cmp);
    for(int i=1;i<=cur;i++) ans[x]=max(ans[x],ans[b[i]]+i);
}
inline void dfs2(int x,int pre)
{
    int t=0;
    if(pre) ans[0]=g[x],b[++t]=0;
    for(int i=head[x];i;i=edge[i].nxt)
    {
    int v=edge[i].to;
    if(v==pre) continue;
    b[++t]=v;
    }
    sort(&b[1],&b[t+1],cmp);
    pref[0]=suf[t+1]=0;
    for(int i=1;i<=t;i++) pref[i]=max(pref[i-1],ans[b[i]]+i);
    ans1=min(ans1,pref[t]);
    for(int i=t;i;i--) suf[i]=max(suf[i+1],ans[b[i]]+i-1);
    for(int i=1;i<=t;i++)
    if(b[i])
        g[b[i]]=max(pref[i-1],suf[i+1]);
    for(int i=head[x];i;i=edge[i].nxt)
    {
    int v=edge[i].to;
    if(v!=pre)
        dfs2(v,x);
    }
}
inline void dfs3(int x,int pre)
{
    for(int i=head[x];i;i=edge[i].nxt)
    {
    int v=edge[i].to;
    if(v==pre) continue;
    ffa[v]=x;
    dfs3(v,x);
    }
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    #endif
    scanf("%d%d%d",&n,&A,&B);
    for(int i=1;i<n;i++)
    {
    int x,y;
    scanf("%d%d",&x,&y);
    add(x,y),add(y,x);
    }
    dfs1(1,0,0);
    ans1=n-1;
    dfs2(1,0);
    printf("%d\n",ans1);
    
    dfs3(A,0);
    int now=B,top=0;
    while(now) c[++top]=now,now=ffa[now];
    int l=1,r=top-1;
    ans2=n-1;
    while(l<=r)
    {
    int mid=(l+r)>>1;
    dfs1(A,0,c[mid]);
    dfs1(B,0,c[mid+1]);
    ans2=min(ans2,max(ans[A],ans[B]));
    if(ans[A]>ans[B]) l=mid+1;
    else r=mid-1;
    }
    printf("%d\n",ans2);
    return 0;
}

T3ツリー

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define MAXN 100010
#define mod 1000000007
using namespace std;
int n,m;
int f[MAXN][11],fa[MAXN],st[MAXN];
inline int fpow(int x,int y)
{
    int cur_ans=1;
    while(y)
    {
        if(y&1) cur_ans=1ll*cur_ans*x%mod;
        x=1ll*x*x%mod;
        y>>=1;
    }
    return cur_ans;
}
inline void dp(int x,int y)
{
    for(int i=10;i;i--)
        for(int j=1;j<i;j++)
            f[x][i]=(f[x][i]+1ll*f[x][j]*f[y][i-j]%mod)%mod;
}
inline void dp2(int x,int y)
{
    for(int i=1;i<=10;i++)
        for(int j=1;j<i;j++)
            f[x][i]=(f[x][i]-1ll*f[x][j]*f[y][i-j]%mod)%mod;
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    freopen("ce.out","w",stdout);
    #endif
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) scanf("%d",&f[i][1]);
    for(int i=2;i<=n;i++) scanf("%d",&fa[i]);
    for(int i=n;i>1;i--) dp(fa[i],i);
    for(int p=1;p<=m;p++)
    {
        int op,k,s,t,top;
        scanf("%d%d%d",&op,&k,&s);
        if(op==1)
        {
            for(int i=1;i<=10;i++) f[0][i]=0;
            for(t=k,top=0;t&&top<10;t=fa[t]) st[++top]=t;
            while(t=st[top--])
            {
                for(int i=1;i<=10;i++) 
                    f[n+1][i]=f[0][i],f[0][i]=f[t][i];
                dp(0,n+1);
                if(top) dp2(0,st[top]);
            }
            printf("%d\n",(f[0][s]+mod)%mod);
        }
        else
        {
            for(t=k,top=0;t&&top<10;t=fa[t]) st[++top]=t;
            for(int i=top-1;i;i--) dp2(st[i+1],st[i]);
            int cur_ans=1ll*fpow(f[k][1],mod-2)*s%mod;
            for(int i=1;i<=10;i++) 
                f[k][i]=1ll*f[k][i]*cur_ans%mod;
            for(int i=1;i<top;i++)
                dp(st[i+1],st[i]);
        }
    }
    return 0;
}

DY4

T1ツリー

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define MAXN 3010
using namespace std;
int n,q,k,t,ans=0x3f3f3f3f;
int dp[MAXN][MAXN][3],siz[MAXN],head[MAXN];
struct Edge{int nxt,to,dis;}edge[MAXN<<1];
inline void add(int from,int to,int dis)
{
    edge[++t].nxt=head[from],edge[t].to=to,edge[t].dis=dis;
    head[from]=t;
}
inline void solve(int x,int pre)
{
    siz[x]=1;
    dp[x][1][0]=dp[x][1][1]=dp[x][1][2]=0;
    dp[x][0][0]=dp[x][0][1]=dp[x][0][2]=0;
    for(int i=head[x];i;i=edge[i].nxt)
    {
        int v=edge[i].to;
        if(v==pre) continue;
        solve(v,x);
//      printf("x=%d v=%d\n",siz[x],siz[v]);
        for(int j=min(k,siz[x]+siz[v]);j>=2;j--)
        {
            for(int j2=max(1,j-siz[x]);j2<=min(j,siz[v]);j2++)//v_size
            {
                int j1=j-j2;//x_size
//              cout<<j2<<" "<<j2<<endl;
                dp[x][j][0]=min(dp[x][j][0],dp[x][j1][0]+dp[v][j2][0]+edge[i].dis*2);
                dp[x][j][1]=min(dp[x][j][1],dp[x][j1][0]+dp[v][j2][1]+edge[i].dis);
                dp[x][j][1]=min(dp[x][j][1],dp[x][j1][1]+dp[v][j2][0]+edge[i].dis*2);
                dp[x][j][2]=min(dp[x][j][2],dp[x][j1][1]+dp[v][j2][1]+edge[i].dis);
                dp[x][j][2]=min(dp[x][j][2],dp[x][j1][2]+dp[v][j2][0]+edge[i].dis*2);
                dp[x][j][2]=min(dp[x][j][2],dp[x][j1][0]+dp[v][j2][2]+edge[i].dis*2);
            }
        }
        siz[x]+=siz[v];
    }
    ans=min(ans,dp[x][k][2]);
//  printf("x=%d %d\n",x,ans);
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    #endif
    scanf("%d%d",&n,&k);
    for(int i=1;i<n;i++)
    {
        int u,v,w;
        scanf("%d%d%d",&u,&v,&w);
        add(u,v,w),add(v,u,w);
    }
    memset(dp,0x3f,sizeof(dp));
    solve(1,0);
    printf("%d\n",ans);
    return 0;
}

T2

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define MAXN 10000000
#define mod 998244353
using namespace std;
int n,k,T;
int inv[MAXN+10],ff[MAXN+10],fn[MAXN+10],F[MAXN+10];
inline int fpow(int x,int y)
{
    int cur_ans=1;
    while(y)
    {
        if(y&1) cur_ans=1ll*cur_ans*x%mod;
        x=1ll*x*x%mod;
        y>>=1;
    }
    return cur_ans;
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    #endif
    scanf("%d%d%d",&n,&k,&T);
    if(T==1) 
    {
        printf("1\n");
        return 0;
    }
    fn[0]=1;
    for(int i=1;i<=MAXN;i++) fn[i]=1ll*fn[i-1]*i%mod;
    inv[MAXN]=fpow(fn[MAXN],mod-2);
    for(int i=MAXN-1;i>=0;i--) inv[i]=1ll*inv[i+1]*(i+1)%mod;
    for(int i=1;i<=MAXN;i++) ff[i]=1ll*inv[i]*fn[i-1]%mod;
    int cur_ans=1;
    int cur=fpow(T-1,mod-2);
    F[0]=1ll*T*(mod-cur)%mod*(1-fpow(T,n)+mod)%mod;
    for(int i=1;i<=k;i++)
    {
        cur_ans=1ll*cur_ans*(n-i+1)%mod*ff[i]%mod;
        F[i]=(1ll*F[i-1]-1ll*T*cur_ans%mod+mod)%mod;
        F[i]=1ll*F[i]*cur%mod;
    }
    cur_ans=fpow(cur_ans,mod-2);
    printf("%lld\n",1ll*cur_ans*F[k-1]%mod);
    return 0;
}

T3

速読このボードは非常に良い質問qwqwqを感じます

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<algorithm>
#define MAXN 1000010
using namespace std;
namespace io {
    const int SIZE = (1 << 21) + 1;
    char ibuf[SIZE], *iS, *iT, obuf[SIZE], *oS = obuf, *oT = oS + SIZE - 1, c, qu[55]; int qr;
    // getchar
    #define gc() (iS == iT ? (iT = (iS = ibuf) + fread (ibuf, 1, SIZE, stdin), (iS == iT ? EOF : *iS ++)) : *iS ++)
    // print the remaining part
    inline void flush () {
        fwrite (obuf, 1, oS - obuf, stdout);
        oS = obuf;
    }
    // putchar
    inline void putc (char x) {
        *oS ++ = x;
        if (oS == oT) flush ();
    }
    // input a integer
    template <class I>
    inline void gi (I &x) {
        for (c = gc(); c < '0' || c > '9'; c = gc());
        for (x = 0; c <= '9' && c >= '0'; c = gc()) x = x * 10 + (c & 15);
    }
    // print a integer
    template <class I>
    inline void print (I &x) {
        if (!x) putc ('0');
        while (x) qu[++ qr] = x % 10 + '0',  x /= 10;
        while (qr) putc (qu[qr --]);
    }
}
using io :: gi;
using io :: putc;
using io :: print;
int n,Q;
int a[MAXN],p[MAXN],pos[MAXN],ans[MAXN],head[MAXN];
struct Node{int l,d,id,nxt;}q[MAXN];
inline void insert(int &x,int k)
{
    for(int i=30;i>=0;i--)
    {
        if(x&(1<<i)) 
        {
            if(!p[i]) {p[i]=x,pos[i]=k;return;}
            if(k>pos[i]) swap(k,pos[i]),swap(p[i],x);
            x^=p[i];
        }
    }
}
inline int query(int cur_ans,int l)
{
    for(int i=30;i>=0;i--)
        if(l<=pos[i]&&(cur_ans^p[i])>cur_ans) 
            cur_ans=cur_ans^p[i];
    return cur_ans;
}
int main()
{
    gi(n);
    for(int i=1;i<=n;i++) gi(a[i]);
    gi(Q);
    for(int i=1;i<=Q;++i)
    {
        int l,r,d;
        gi(l),gi(r),gi(d); 
        q[i]=(Node){l,d,i,head[r]};
        head[r]=i;
    }
    for(int i=1;i<=n;++i)
    {
        insert(a[i],i);
//      for(int i=0;i<=10;i++) printf("p[%d]=%d\n",i,p[i]);
        for(int j=head[i];j;j=q[j].nxt) 
            ans[q[j].id]=query(q[j].d,q[j].l);
    }
    for(int i=1;i<=Q;++i) print(ans[i]),putc('\n');
    io::flush();
    return 0;
}

Day5

T1ツリー

T2の順列

場所間違った行の問題制限があります。

  • 10pts列挙配置は、それが正しいかどうかを決定します。時間複雑\(O(N!N) \)
  • 100pts我々は、包含と除外を検討してください。
    私たちは、明らかに結果がされ、何の制限間違った行が存在しない場合、あなたは、この位置を保持し、位置の値は単に無視見てきました\((NK)を!\)です。
    しかし、この部分は間違っているが、このようなプット1、我々はこれの例数、つまり、マイナス見当違い取り除くこの場合で、右、間違っている\(C_ {M} ^ 1 (NK-1)! \)
    が、より多くのこのようなので、追加するために、例えば、この場合、二つの数置き忘れ1,2- 1,2に、低減することができる\(C_ {M} ^ 2
    (NK-2)!\) .......など、それが答えです。
    スタートの数はLET行くされている場合は注意している、そして我々はそれを無視する必要はありません。
    数mは、元の配置でもないので、 、それは数に対応する数でない場合。

(最後の診察(ANS + MOD)%MODを忘れ)、及び40に吹き付け.......
ACコード:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#define MAXN 1000010
#define mod 998244353
using namespace std;
int n;
int p[MAXN];
namespace subtask1 //10pts
{
    int ans,cnt;
    int done[MAXN],cur[MAXN];
    inline void search(int x)
    {
        if(x>n)
        {
//          for(int i=1;i<=n;i++) printf("%d ",cur[i]); puts("");
            ans++;
            return;
        }
        if(p[x]){cur[++cnt]=p[x];search(x+1);cnt--;return;}
        for(int i=1;i<=n;i++)
        {
            if(done[i]||i==x) continue;
            done[i]=1;cur[++cnt]=i;
            search(x+1);
            done[i]=0;cnt--;
        }
    }
    inline void solve()
    {
        for(int i=1;i<=n;i++) if(p[i]) done[p[i]]=1;
        search(1);
        printf("%d\n",ans);
    }
}
namespace subtask2
{
    int fn[MAXN],inv[MAXN],f[MAXN],done[MAXN];
    inline int fpow(int x,int y)
    {
        int cur_ans=1;
        while(y)
        {
            if(y&1) cur_ans=1ll*cur_ans*x%mod;
            x=1ll*x*x%mod;
            y>>=1;
        }
        return cur_ans;
    }
    inline void init()
    {
        fn[0]=1;
        for(int i=1;i<=MAXN-10;i++) fn[i]=1ll*fn[i-1]*i%mod;
        inv[MAXN-10]=fpow(fn[MAXN-10],mod-2);
        for(int i=MAXN-10-1;i>=0;i--) inv[i]=1ll*inv[i+1]*(i+1)%mod;
//      for(int i=0;i<5;i++) printf("fn[%d]=%d\n",i,fn[i]);
//      for(int i=0;i<5;i++) printf("inv[%d]=%d\n",i,inv[i]);
    }
    inline int C(int x,int y)
    {
        if(y==0||x==y) return 1;
        if(y>x) return 0;
        return 1ll*fn[x]*inv[y]%mod*inv[x-y]%mod; 
    }
    inline void solve()
    {
        init();
        int m=0,ans=0,g=1,k=0;
        for(int i=1;i<=n;i++) 
        {
            if(p[i]) 
                k++,done[p[i]]=1;
        }
        for(int i=1;i<=n;i++)
            if(done[i]==0&&p[i]==0) m++;
        for(int i=0;i<=m;i++)
        {
//          cout<<fn[n-k-1]<<" "<<C(m,i)<<endl;
            ans=(ans+1ll*g*fn[n-k-i]%mod*C(m,i))%mod;
            g*=-1;
//          printf("i=%d ans=%d\n",i,ans);
        }
        printf("%d\n",(ans+mod)%mod);
    }
}
using namespace subtask1;
using namespace subtask2;
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    #endif
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&p[i]);
    if(n<=10) subtask1::solve();
    else subtask2::solve();
    return 0;
}

T3の色

  • 20pts暴力列挙各側面の状態、およびあなたは判断することができます。時間複雑\(O(N ^ 2 2 ^ n個)\)
  • 40(= 20 + 20)答えは各点に明らかに等しく、ストランドの状態をPTS (iが(N-I * \ + 1)\)
  • 我々はセット60(= 20 + 40)PTS \を(DP [I] \)私はツリーのルートである子への答えを表し、我々はルートとしてどのような各点を列挙し、あなたは答えを見つけ出すことができます。時間複雑\(O(N ^ 2) \)
  • 100pts我々はルートDPに変更を加えるのn離れてルート最適化を列挙する。時間の複雑さ(GG上の0の逆数を乗じた---> 70ポイントにリンクする場合は、この質問の蓄積動作への答えは、乗算であるので、しかし、時間の影響を除去することは、直接逆加えすることができないことに注意してください)\ (O(N)\)
    ACコード:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#define MAXN 100010
#define mod 1000000007
using namespace std;
int n,t;
int fa[MAXN],dp[MAXN],head[MAXN];
int up[MAXN],pref[MAXN],suf[MAXN],b[MAXN];
struct Edge{int nxt,to;}edge[MAXN<<1];
vector<int>e[MAXN];
inline void add(int from,int to)
{
    edge[++t].nxt=head[from],edge[t].to=to;
    head[from]=t;
}
inline int fpow(int x,int y)
{
    int cur_ans=1;
    while(y)
    {
        if(y&1) cur_ans=1ll*cur_ans*x%mod;
        x=1ll*x*x%mod;
        y>>=1;
    }
    return cur_ans;
}
inline void init(int x,int pre)
{
    dp[x]=1;
    for(int i=head[x];i;i=edge[i].nxt)
    {
        int v=edge[i].to;
        if(v==pre) continue;
        init(v,x);
        dp[x]=1ll*dp[x]*(dp[v]+1)%mod;
//      dp[x]=(dp[x]+1ll*dp[x]*(dp[v]+1))%mod;
    }
}
inline void change_root(int x,int pre)
{
    dp[x]=1ll*dp[x]*(up[x]+1)%mod;
    int cnt=0;
    for(int i=head[x];i;i=edge[i].nxt)
    {
        int v=edge[i].to;
        if(v==pre) continue;
        b[++cnt]=dp[v];
    }
    pref[0]=(up[x]+1)%mod;
    suf[cnt+1]=1;
    for(int i=1;i<=cnt;i++) pref[i]=1ll*pref[i-1]*(b[i]+1)%mod;
    for(int i=cnt;i>=1;i--) suf[i]=1ll*suf[i+1]*(b[i]+1)%mod;
    cnt=0;
    for(int i=head[x];i;i=edge[i].nxt)
    {
        int v=edge[i].to;
        if(v==pre) continue;
        cnt++;
        up[v]=1ll*pref[cnt-1]*suf[cnt+1]%mod;
    }
    for(int i=head[x];i;i=edge[i].nxt)
    {
        int v=edge[i].to;
        if(v==pre) continue;
        change_root(v,x);
    }
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    #endif
    scanf("%d",&n);
    for(int i=2;i<=n;i++) 
    {
        scanf("%d",&fa[i]);
        add(fa[i],i),add(i,fa[i]);
        e[fa[i]].push_back(i);
        e[i].push_back(fa[i]);
    }
    init(1,0);
//  for(int i=1;i<=n;i++) up[i]=1;
    change_root(1,0);
    for(int i=1;i<=n;i++) printf("%d ",dp[i]);
    return 0;
}

おすすめ

転載: www.cnblogs.com/fengxunling/p/10980035.html