CSP2019QwQ

試著忘記壹切 提交于 2020-03-21 10:52:10

咕咕咕~~~
话说这篇咕了好久到现在才开始写(暂时还是不会\(day1T3\),先欠着),后来到改才发现其实CSP2019不是很难?
先码题解

\(day1T1\)

傻逼题,不解释,确实对得起黄题的难度,这里思路是随便用个递归搞掉\(1A\)过算了
当然还可以用循环?,复杂度\(O(logk)\)?
代码:

#include<bits/stdc++.h>
using namespace std;

#define ll unsigned long long

inline void read(ll &x)
{
    x=0;char ch=getchar();
    for(;!isalnum(ch);ch=getchar());
    for(;isalnum(ch);ch=getchar()) x=x*10+ch-'0';
}

ll fac[64];

inline void sol(ll n,ll k)
{
    if(n==1)
    {
        cout<<k?1:0;
        return;
    }
    if(k>=fac[n-1])
    {
        cout<<1;
        sol(n-1,fac[n-1]-k+fac[n-1]-1);
    }
    else
    {
        cout<<0;
        sol(n-1,k);
    }
}

int main()
{
    ll n,k;read(n);read(k);
    fac[0]=1;
    for(register int i=1;i<=63;++i) fac[i]=fac[i-1]<<1;
    sol(n,k);
    return 0;
}

\(day1T2\)

额,话说我考场上连这道绿题都没切掉
天理难容啊
果然还是太蒟蒻了
想出了正解思路,但是脑袋有点乱,不会码,于是从\(100pt\)变成了\(0pt\),难受
一句话题解:一点\(')'\)对答案的贡献是其对应的\('('\)的前一个符号的贡献\(+1\),开栈,回溯\(dfs\).
没了?~~没了T_T……
代码\(O(n)\):

#include<bits/stdc++.h>
using namespace std;

#define ll long long

inline void read(int &x)
{
    x=0;char ch=getchar();
    for(;!isalnum(ch);ch=getchar());
    for(;isalnum(ch);ch=getchar()) x=x*10+ch-'0';
}

const int xx=5e5+11;
int f[xx];
int head[xx],nxt[xx],to[xx],all=0;
ll k[xx],ctr[xx];
int sta[xx],top=0;
char ch[xx];

inline void dfs(int g)
{
    int tmp=0;
    if(ch[g]==')'&&top)
    {
        tmp=sta[top--];
        ctr[g]=ctr[f[tmp]]+1;
    }
    if(ch[g]=='(') sta[++top]=g;
    k[g]=k[f[g]]+ctr[g];
    for(register int v=head[g];v;v=nxt[v])
        dfs(to[v]);
    if(tmp) sta[++top]=tmp;
    if(ch[g]=='(') --top;
}

int main()
{
    int n;read(n);
    scanf("%s",ch+1);
    for(register int i=2;i<=n;++i)
    {
        read(f[i]);
        nxt[++all]=head[f[i]];
        to[all]=i;
        head[f[i]]=all;
    }
    dfs(1);
    ll ans=0;
    for(register int i=1;i<=n;++i)
        ans^=(i*k[i]);
    cout<<ans<<endl;
    return 0;
}

\(day1T3\)

咕咕咕~~~
妈呀,黑题,不码了
咕咕咕~~~

\(day2T1\)

话说硬是没看出来这是\(DP\),一直以为是数学,想到了容斥,结果没思路,想打份\(O(n2^m)\)的爆搜的,结果不知道哪里锅了,没调出来
自闭.jpg
于是看到\(DP\)就醍醐灌顶了
但想不到真的不能怪我啊,蒟蒻dp不好
容斥思路走一波,显然若有超过\(k/2\)的食材则仅有一种,于是总方案减不合法方案即为所求
\(s_i\)为第\(i\)行种类数总和,\(ex_{i,j}\)为第\(i\)行除\(a_{i,j}\)种类数总和,\(f_{i,j}\)为当前列(不合法列)\(DP\)到第\(i\)行,并且当前列的选择比其他列多\(j\)种的方案数(\(j\in [-n,n]\)),\(g_{i,j}\)为当前(整体)\(DP\)到第\(i\)行,并且已经选择了\(j\)种的方案数
易知:
\[f_{i,j}=f_{i-1,j}+f_{i-1,j-1}*a_{i,j}+f_{i-1,j+1}*ex_{i,j}~~~~~,~~~~~g_{i,j}=g_{i,j-1}*s_i\]
\[\text{若}all_f=\sum_{k=1}^{m}\sum_{j=1}^{n}f_{n,j}~~~,~~~\text{则}ans=\sum_{j=1}^{n}g_{n,j}-all_f\]
时间复杂度处理\(f_{i,j}\)\(O(mn^2)\)\(g_{i,j}\)\(O(n^2)\),合起来是\(O(mn^2)\),跑满大概\(2e7\)严重怀疑CCF老爷机跑不跑得动
上代码:

#include<bits/stdc++.h>
using namespace std;

#define ll long long
const ll mod=998244353;
const int xn=110,xm=2010;

inline void read(ll &x)
{
    x=0;char ch=getchar();
    for(;!isalnum(ch);ch=getchar());
    for(;isalnum(ch);ch=getchar()) x=x*10+ch-'0';
}

ll a[xn][xm],s[xn],ex[xn][xm];
ll f[xn][xn<<1],g[xn][xn];
ll ans1=0,ans2=0,n,m;

inline void build_f()
{
    for(register int i=1;i<=m;++i)
    {
        memset(f,0,sizeof(f));
        f[0][n]=1;
        for(register int j=1;j<=n;++j)  
            for(register int k=n-j;k<=n+j;++k)
            {
                f[j][k]=f[j-1][k];
                (f[j][k]+=(f[j-1][k-1]*a[j][i]%mod))%=mod;
                (f[j][k]+=(f[j-1][k+1]*ex[j][i]%mod))%=mod;
            }
        for(register int k=n+1;k<=(n<<1);++k) (ans2+=f[n][k])%=mod;
    }
}
inline void build_g()
{
    g[0][0]=1;
    for(register int j=1;j<=n;++j)
        for(register int k=1;k<=j;++k)
        {
            g[j][k]=g[j-1][k];
            (g[j][k]+=(k>1?(g[j-1][k-1]*s[j]%mod):s[j]))%=mod;
        }
    for(register int k=1;k<=n;++k) (ans1+=g[n][k])%=mod;
}

int main()
{
    read(n);read(m);
    for(register int i=1;i<=n;++i)
    {
        s[i]=0;
        for(register int j=1;j<=m;++j)
        {
            read(a[i][j]);
            (s[i]+=a[i][j])%=mod;
        }
        for(register int j=1;j<=m;++j) ex[i][j]=((s[i]-a[i][j])%mod+mod)%mod;
    }
    build_f();
    build_g();
    ll ans=((ans1-ans2)%mod+mod)%mod;
    printf("%lld\n",ans);
    return 0;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!