ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Codeforces Round #564 (Div. 1)

2019-06-25 18:40:33  阅读:238  来源: 互联网

标签:ch return EOF int 564 Codeforces read Div define


Codeforces Round #564 (Div. 1)

A Nauuo and Cards

首先如果牌库中最后的牌是\(1,2,\cdots, k\),那么就模拟一下能不能每次打出第\(k+i\)张牌。

然后考虑每一张牌打出后还要打多少张牌以及这张牌是什么时候入手的,分别记为\(f_i,g_i\),那么答案就是\(f_i+g_i\)的最大值。

#include<bits/stdc++.h>
#define qmin(x,y) (x=min(x,y))
#define qmax(x,y) (x=max(x,y))
#define pir pair<int,int>
#define mp(x,y) make_pair(x,y)
#define fr first
#define sc second
#define rsort(x,y) sort(x,y),reverse(x,y)
#define vic vector<int>
#define vit vic::iterator
using namespace std;

char gc() {
//  static char buf[100000],*p1,*p2;
//  return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
    return getchar();
}

template<class T>
int read(T &ans) {
    T f=1;ans=0;
    char ch=gc();
    while(!isdigit(ch)) {
        if(ch==EOF) return EOF;
        if(ch=='-') f=-1;
        ch=gc();
    }
    while(isdigit(ch))
        ans=ans*10+ch-'0',ch=gc();
    ans*=f;return 1;
}

template<class T1,class T2>
int read(T1 &a,T2 &b) {
    return read(a)==EOF?EOF:read(b);
}

template<class T1,class T2,class T3>
int read(T1 &a,T2 &b,T3 &c) {
    return read(a,b)==EOF?EOF:read(c);
}

typedef long long ll;
const int Maxn=1100000;
const int inf=0x3f3f3f3f;
const ll mod=998244353;

int n,a[Maxn],b[Maxn],c[Maxn],x,ans;

bool work() {
    for(int i=1;i<=n;i++) c[i]=b[i];
    int now=1;
    for(int i=a[n]+1;i<=n;i++) {
        if(!c[i]) return false;
        c[a[now++]]++;
    }
    return true;
}

int main() {
//  freopen("test.in","r",stdin);
    read(n);
    for(int i=1;i<=n;i++) read(x),b[x]++;
    for(int i=1;i<=n;i++) read(a[i]);
    int sxz=0;
    for(int i=1;i<=n;i++) {
        if(a[i]==1) {
            int flag=0;
            for(int j=1;j<=n-i;j++) if(a[i+j]!=j+1) {
                flag=1;
                break;
            }
            if(!flag) sxz=i;
            break;
        }
    }
    if(sxz&&work()) return 0*printf("%d\n",n-a[n]);
    else {
        memset(c,0,sizeof(c));
        for(int i=1;i<=n;i++) if(a[i]) c[a[i]]=i;
        for(int i=1;i<=n;i++) qmax(ans,c[i]+n-i+1);
        printf("%d\n",ans);
    }
    return 0;
}

B Nauuo and Circle

除了根以外,每一颗子树在圆上一定是一段弧,设这颗子树根节点有\(x\)个儿子,那么这颗子树的方案数为\(f_i=(x+1)!\prod_{j\in son(i)}f_j\)。因为除了要给\(x\)个儿子做排列,还要考虑到根节点插到哪个位置。

而根的区别在于根对应的是整个圆,那么就不需要考虑根要插到哪个位置,方案数即为\(f_i=x!\prod_{j\in son(i)}f_j\)。圆可以旋转,所以要再乘以一个\(n\)。

#include<bits/stdc++.h>
#define qmin(x,y) (x=min(x,y))
#define qmax(x,y) (x=max(x,y))
#define pir pair<int,int>
#define mp(x,y) make_pair(x,y)
#define fr first
#define sc second
#define rsort(x,y) sort(x,y),reverse(x,y)
#define vic vector<int>
#define vit vic::iterator
using namespace std;

char gc() {
//  static char buf[100000],*p1,*p2;
//  return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
    return getchar();
}

template<class T>
int read(T &ans) {
    T f=1;ans=0;
    char ch=gc();
    while(!isdigit(ch)) {
        if(ch==EOF) return EOF;
        if(ch=='-') f=-1;
        ch=gc();
    }
    while(isdigit(ch))
        ans=ans*10+ch-'0',ch=gc();
    ans*=f;return 1;
}

template<class T1,class T2>
int read(T1 &a,T2 &b) {
    return read(a)==EOF?EOF:read(b);
}

template<class T1,class T2,class T3>
int read(T1 &a,T2 &b,T3 &c) {
    return read(a,b)==EOF?EOF:read(c);
}

typedef long long ll;
const int Maxn=1100000;
const int inf=0x3f3f3f3f;
const ll mod=998244353;

int to[Maxn],nxt[Maxn],first[Maxn],tot=1,dp[Maxn],n,u,v;

inline void add(int u,int v) {
    to[tot]=v;
    nxt[tot]=first[u];
    first[u]=tot++;
    to[tot]=u;
    nxt[tot]=first[v];
    first[v]=tot++;
}

void dfs(int root,int fa=0) {
    int x=1,y=1,temp=1;
    for(int i=first[root];i;i=nxt[i]) {
        if(to[i]!=fa) {
            dfs(to[i],root);
            x=1ll*x*temp%mod; temp++;
            y=1ll*y*dp[to[i]]%mod;
        }
    }
    x=1ll*x*temp%mod;
    dp[root]=1ll*x*y%mod;
}

int main() {
//  freopen("test.in","r",stdin);
    read(n);
    for(int i=1;i<n;i++) {
        read(u,v);
        add(u,v);
    }
    int x=1,y=1,temp=1;
    for(int i=first[1];i;i=nxt[i]) {
        dfs(to[i],1);
        x=1ll*x*temp%mod; temp++;
        y=1ll*y*dp[to[i]]%mod;
    }
    dp[1]=1ll*x*y%mod;
    printf("%I64d\n",1ll*n*dp[1]%mod);
    return 0;
}

C Nauuo and Pictures

一开始我们猜想直接按照当前的期望值作为权重,但是这个是不对的,因为一个是加,而另一个是减,这两个会互相影响。

但是在所有要加的数里面,每个数期望占的比例是不变的,所以我们可以把所有加的合成一个,所有减的合成一个,然后就可以\(O(m^2)\)DP了,最后按照每个数初始所占的比例还原回去就好了。

#include<bits/stdc++.h>
#define qmin(x,y) (x=min(x,y))
#define qmax(x,y) (x=max(x,y))
#define pir pair<int,int>
#define mp(x,y) make_pair(x,y)
#define fr first
#define sc second
#define rsort(x,y) sort(x,y),reverse(x,y)
#define vic vector<int>
#define vit vic::iterator
using namespace std;

char gc() {
//  static char buf[100000],*p1,*p2;
//  return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
    return getchar();
}

template<class T>
int read(T &ans) {
    T f=1;ans=0;
    char ch=gc();
    while(!isdigit(ch)) {
        if(ch==EOF) return EOF;
        if(ch=='-') f=-1;
        ch=gc();
    }
    while(isdigit(ch))
        ans=ans*10+ch-'0',ch=gc();
    ans*=f;return 1;
}

template<class T1,class T2>
int read(T1 &a,T2 &b) {
    return read(a)==EOF?EOF:read(b);
}

template<class T1,class T2,class T3>
int read(T1 &a,T2 &b,T3 &c) {
    return read(a,b)==EOF?EOF:read(c);
}

typedef long long ll;
#define int long long 
const int Maxn=1100000;
const int inf=0x3f3f3f3f;
const ll mod=998244353;

int n,m,a[Maxn],b[Maxn],sxz,zhy,f[3100][3100],ansx,ansy;

ll powp(ll a,ll b) {
    ll ans=1;
    while(b) {
        if(b&1) ans=ans*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return ans;
}

signed main() {
//  freopen("test.in","r",stdin);
    read(n,m);
    for(int i=1;i<=n;i++) read(a[i]);
    for(int i=1;i<=n;i++) read(b[i]);
    for(int i=1;i<=n;i++)
        if(a[i]) sxz=(sxz+b[i])%mod;
        else zhy=(zhy+b[i])%mod;
    f[0][0]=1;
    for(int i=1;i<=m;i++)
        for(int j=0;j<i;j++) {
            if(i-j-1==zhy) f[j+1][i-j-1]=(f[j+1][i-j-1]+f[j][i-j-1])%mod;
            else {
                int x=sxz+j,y=zhy-(i-j-1),tot=powp(x+y,mod-2);
                f[j+1][i-j-1]=(f[j+1][i-j-1]+1ll*f[j][i-j-1]*x%mod*tot%mod)%mod;
                f[j][i-j]=(f[j][i-j]+1ll*f[j][i-j-1]*y%mod*tot%mod)%mod;
            }
        }
    for(int i=0;i<=m;i++)
        ansx=(ansx+1ll*f[i][m-i]*i%mod)%mod,ansy=(ansy+1ll*f[i][m-i]*(m-i)%mod)%mod;
    int x=(sxz+ansx)%mod,y=(zhy-ansy+mod)%mod;
    sxz=powp(sxz,mod-2),zhy=powp(zhy,mod-2);
    for(int i=1;i<=n;i++) if(a[i]) printf("%I64d\n",sxz*b[i]%mod*x%mod);
    else printf("%I64d\n",zhy*b[i]%mod*y%mod);
    return 0;
}

D Nauuo and Portals

考虑初始时向右走的人从上到下编号为\(a_i\),向下走的人从左到右编号为\(b_i\),而最终向右走到达第\(i\)行的终点的人的编号为\(r_i\),向下为\(c_i\)。

如果\(a_1==r_1\ and\ b_1==c_1\),那么直接把第一行和第一列去掉就好了。

那么找到\(a_x==r_1\ ,\ b_y==c_1\),那么就加上一个门:\(<(x,1),(1,y)>\),然后交换\(a_x,a_1\)和\(b_y,b_1\),也可以把第一行和第一列去掉。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cctype>
#define qmin(x,y) (x=min(x,y))
#define qmax(x,y) (x=max(x,y))
#define vic vector<int>
#define vit vic::iterator
#define pir pair<int,int>
#define fr first
#define sc second
#define mp(x,y) make_pair(x,y)
#define rsort(x,y) sort(x,y),reverse(x,y)
using namespace std;

inline char gc() {
//  static char buf[100000],*p1,*p2;
//  return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
    return getchar();
}

template<class T>
int read(T &ans) {
    ans=0;char ch=gc();T f=1;
    while(!isdigit(ch)) {
        if(ch==EOF) return -1;
        if(ch=='-') f=-1;
        ch=gc();
    }
    while(isdigit(ch))
        ans=ans*10+ch-'0',ch=gc();
    ans*=f;return 1;
}

template<class T1,class T2>
int read(T1 &a,T2 &b) {
    return read(a)!=EOF&&read(b)!=EOF?2:EOF;
}

template<class T1,class T2,class T3>
int read(T1 &a,T2 &b,T3 &c) {
    return read(a,b)!=EOF&&read(c)!=EOF?3:EOF;
}

typedef long long ll;
const int Maxn=1100;
const int inf=0x3f3f3f3f;

int a[Maxn],b[Maxn],r[Maxn],c[Maxn];
int n,x,tot;
pair<pir,pir> ans[Maxn];

void work(int x) {
    if(x==n) return ;
    if(a[x]==r[x]&&b[x]==c[x]) work(x+1);
    else {
        int y,z;
        for(int i=x;i<=n;i++) if(a[i]==r[x]) {
            y=i;
            break;
        }
        for(int i=x;i<=n;i++) if(b[i]==c[x]) {
            z=i;
            break;
        }
        swap(a[y],a[x]); swap(b[z],b[x]);
        ans[++tot]=mp(mp(y,x),mp(x,z));
        work(x+1);
    }
}

signed main() {
//  freopen("test.in","r",stdin);
    read(n);
    for(int i=1;i<=n;i++) read(x),r[x]=i;
    for(int i=1;i<=n;i++) read(x),c[x]=i;
    for(int i=1;i<=n;i++) a[i]=b[i]=i;
    work(1);
    printf("%d\n",tot);
    for(int i=1;i<=tot;i++) {
        printf("%d %d %d %d\n",ans[i].fr.fr,ans[i].fr.sc,ans[i].sc.fr,ans[i].sc.sc);
    }
    return 0;
}

标签:ch,return,EOF,int,564,Codeforces,read,Div,define
来源: https://www.cnblogs.com/shanxieng/p/11084580.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有