咕咕咕~~~
话说这篇咕了好久到现在才开始写(暂时还是不会\(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;
}