noi.ac NOI Challenge Camp simulation game 1-5

Note: Because the blogger is a zero every test explosion bottom of the dish of chicken, so on this blog is likely to Gugu Gu

(Refers only AC paste the code does not write the solution to a problem ...... If I do not do it, I can not blame the qwqwq)


Day1

T1 swap

  • 23pts burst start the search from a state, then we look at the state of the hash to ensure that a state is only accessed once. Time complexity \ (O (the n-! The n-) \) , complex feeling spent 55 minutes no problem, but will be back to RE ....... I do not know why ah QAQ
  • 55pts enumerated at this later arrangement, then we look at each of the two by determining a width greater than n person did not replace the legitimacy of the relative position determined end state (refer to the relative position if the original pos_x <pos_y, after still less than pos_x 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;
}

Compare gods out of practice, what we deal with small to large. For the smallest number of the current, we judge it and the current maximum number can not be exchanged;
if it and the largest exchange, then it and the current number of all numbers inside the column can be switched (meaning the last position there is the current number in the sequence number -> n species) so we can give an answer multiplied by n, then remove the minimum number, for the rest of the sequence recursive computation (because the final sequence, whether this is what the situation, can be inserted in a minimum number of ways to n among them constitute the answer);
if it does not and the largest exchange, the largest of any of a number can not be exchanged and the current sequence, so it is useless, and only in its current position on what kind of contribution we deleting it , recursive processing sequences can.

  • 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 State

#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 sequence


Day2

T1 baby

#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 Bike

T3 Boom


Day3

T1 sequence

Fairy fucks 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 game

The code is written in emacs indentation pot ...... so 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 tree

#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 tree

#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

Fast reading this board feel very good question 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 tree

T2 permutation

There are restrictions location wrong row problem.

  • 10pts enumeration arrangement, then determine whether it is right. Time complexity \ (O (n! N) \)
  • 100pts we consider the inclusion and exclusion.
    We have seen the value of the position simply ignored, then you hold this position, if there is no restriction wrong row, apparently the result is \ ((nk)! \) Is.
    But this part is wrong, right, wrong is such a put 1 this case, we get rid of this misplaced a number of cases, that is, minus \ (C_ {m} ^ 1 (nk-1)! \)
    but more like this can reduce, for example, into a 1,2 1,2 misplaced this case two numbers, so to add \ (C_ {m} ^ 2
    (nk-2)! \) ....... and so on, it is the answer.
    which note, if the number of start has been let go, then we do not need to ignore it.
    so the number m is neither their original placement , where it is not the number corresponding to the number.

(Forget the last examination (ans + mod)% mod), and blown to 40 .......
AC Code:

#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 color

  • 20pts violence enumeration state of each side, and then you can judge. Time complexity \ (O (n ^ 2 2 ^ n) \)
  • 40 (= 20 + 20) pts strand state, the answer is clearly equal to each point \ (i * (n-i + 1) \)
  • 60 (= 20 + 40) pts we set \ (dp [i] \) represents the answer to child i is the root of the tree, then we enumerate what each point as the root, you can figure out the answer. Time complexity \ (O (n ^ 2) \)
  • 100pts we add the change to the root DP n enumerate the root optimize away. (But note that removing the influence of time can not be directly inverse addition, because the answer to this question accumulation operation is multiplication, if multiplied by the inverse of a 0 on the GG ---> will be linked to 70 points) time complexity \ (O (n-) \)
    the AC codes:
#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;
}

Guess you like

Origin www.cnblogs.com/fengxunling/p/10980035.html