【NOI2017】泳池

题解:

满分的笛卡尔树以后再学吧。。

40分还是比较好想的

但是状态挺复杂的

直接贴代码了

代码:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define IL inline
#define rint register ll
#define rep(i,h,t) for (rint i=h;i<=t;i++)
#define dep(i,t,h) for (rint i=t;i>=h;i--)
#define me(x) memset(x,0,sizeof(x))
ll n,k,x,y;
ll mo=998244353;
ll f[2][11][6][4][3][3][2][2];
ll ans=0;
void js(ll &x,ll y)
{
  x=(x+y)%mo;
}
void gcd(ll x,ll y,ll &a,ll &b)
{
  if (y==0)
  {
    a=1; b=0; return;
  }
  gcd(y,x%y,b,a);
  b=b-a*(x/y);
}
int main()
{
  freopen("1.in","r",stdin);
  freopen("1.out","w",stdout);
  cin>>n>>k>>x>>y;
  ll x1,y1;
  gcd(y,mo,x1,y1);
  ll pp=(x*x1)%mo;
  int p[2000];
  p[0]=1;
  rep(i,1,k) p[i]=(p[i-1]*pp)%mo;
  rep(i,0,k) p[i]=(p[i]*(1ll-pp))%mo;
  if (n==1)
  {
    cout<<(p[k]%mo+mo)%mo<<endl;
    return 0;
  }
  f[0][0][0][0][0][0][0][0]=1;
   rep(i,1,n)
  {
    ll kk=i%2,tt=(i+1)%2;
    me(f[kk]);
    rep(i,0,k)
    {
      rep(i1,0,k)
      {
        if ((i1+(i>=1))>k) break;
        rep(j1,0,k/2)
        {
          if ((j1+(i>=2))*2>k) break;
          rep(i2,0,k/3)
          {
            if ((i2+(i>=3))*3>k) break; 
            rep(j2,0,k/4)
            {
              if ((j2+(i>=4))*4>k) break;
              rep(i3,0,k/5)
              {
                if ((i3+(i>=5))*5>k) break;
                rep(j3,0,1)
                {    
                  if (j3==1&&i>=6) break;
                  rep(k1,0,1)
                  {
                    bool t=0;
                    if ((i1+(i>=1))==k) t=1;
                    if ((j1+(i>=2))*2==k) t=1;
                    if ((i2+(i>=3))*3==k) t=1; 
                    if ((j2+(i>=4))*4==k) t=1;
                    if ((i3+(i>=5))*5==k) t=1;
                    if (i==k) t=1;
                    js(f[kk][(i>=1)?i1+1:0][(i>=2)?j1+1:0][(i>=3)?i2+1:0][(i>=4)?j2+1:0][(i>=5)?i3+1:0][i>=6][k1|t],
                    f[tt][i1][j1][i2][j2][i3][j3][k1]*p[i]);
                    int ans1=3;
                    ans1++;
                  }
                }
              }
            }
          }
        }
      }
    }
  }
rep(i1,0,10)
  rep(j1,0,5)
    rep(i2,0,3)
      rep(j2,0,2)
        rep(i3,0,2)
          rep(j3,0,1)
            js(ans,f[n%2][i1][j1][i2][j2][i3][j3][1]);
  cout<<(ans%mo+mo)%mo<<endl;
  return 0;
}

 

posted @ 2018-07-17 00:27  尹吴潇  阅读(281)  评论(0编辑  收藏  举报