zoukankan      html  css  js  c++  java
  • 2019 Multi-University Training Contest 1 题解

    1001 - Blank

    $dp$。给的限制条件是一些区间内出现的数字种类数,其实比较容易联想到一个经典的题,就是一个序列以及很多组询问,每个询问查询一个区间内不同种类的数字个数,这个题的一个做法是将询问按右端点升序排序,然后扫描线,用线段树维护每个数字出现的最晚位置。这个题由于数字种类本身很少,只有四种,所以我们可以用$dp[i][a][b][c][d]$来前$i$个位置,四种数字最近出现的位置分别是$a,b,c,d$的方案数,但是这样内存不够,其实有一维是可以省去的,因为$a,b,c,d$中恰有一个是$i$,然后其实我们不用关心具体是哪个数字出现在某个位置,因此,我们可以简化状态,用$dp[i][a][b][c]$表示前$i$个位置,除第$i$个位置的数字外,其他三种数字分别出现在$a,b,c$的方案数,其中$aleq b leq c$,转移比较显然,这里不赘述。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<vector>
     4 const int mod=998244353;
     5 inline void upd(int &a,int x) {
     6     a+=x;
     7     if(a>=mod) a-=mod;
     8 }
     9 const int N=101;
    10 int n,m,dp[2][N][N][N];
    11 typedef std::pair<int,int> P;
    12 std::vector<P> g[N];
    13 int main() {
    14     int T;
    15     scanf("%d",&T);
    16     while(T--) {
    17         scanf("%d%d",&n,&m);
    18         for(int i=1;i<=n;i++) g[i].clear();
    19         for(int l,r,x;m--;) {
    20             scanf("%d%d%d",&l,&r,&x);
    21             g[r].push_back(P(l,x));
    22         }
    23         dp[1][0][0][0]=4;
    24         int ans=0;
    25         for(int i=1;i<=n;i++) {
    26             int t=i&1;
    27             if(i<n) for(int x=0;x<=i;++x) for(int y=x;y<=i;y++) for(int z=y;z<=i;z++) dp[t^1][x][y][z]=0;
    28             for(int x=0;x<i;++x) for(int y=x;y<i;y++) for(int z=y;z<i;z++) if(dp[t][x][y][z]) {
    29                 bool f=true;
    30                 for(auto &c:g[i]) {
    31                     int num=1;
    32                     if(x>=c.first) num+=3;
    33                     else if(y>=c.first) num+=2;
    34                     else if(z>=c.first) num++;
    35                     if(num!=c.second) {
    36                         f=false;
    37                         break;
    38                     }
    39                 }
    40                 if(!f) {
    41                     dp[t][x][y][z]=0;
    42                     continue;
    43                 }
    44                 if(i==n) upd(ans,dp[t][x][y][z]);
    45                 else {
    46                     upd(dp[t^1][x][y][z],dp[t][x][y][z]);
    47                     upd(dp[t^1][y][z][i],dp[t][x][y][z]);
    48                     upd(dp[t^1][x][z][i],dp[t][x][y][z]);
    49                     upd(dp[t^1][x][y][i],dp[t][x][y][z]);
    50                 }
    51             }
    52         }
    53         printf("%d
    ",ans);
    54     }
    55     return 0;
    56 }
    View Code

    1012 - Sequence

    $NTT$。如果我们令$f=sum_{i=1}^n a_ix^i$,$g(c)=sum_{i=0}x^{ci}$,那么经过$m$次操作后,最终的序列的第$i$项,就是$fprod_{i=1}^mg(c_i)$的$x^i$的系数。我们令$h=prod_{i=1}^mg(c_i)$,由此可以看出,操作的顺序对结果是无影响的,由此,我们可以按$c_i$的值分类计算。首先我们考虑$c_i=1$的情况,这个时候有$g(1)=sum_{i=0}x^i$,设$c_i=1$的操作有$k$个,那么显然有$g(1)^k=sum_{i=0}C_{i+k-1}^{i}x^i$,因为这相当于是在计算将$i$个无区别的物品放入$k$个有区别的箱子中的方案数。对于$c_i=2$以及$c_i=3$的情况,其实计算是一样的,这里不赘述,最后我们用$NTT$加速乘法即可。

  • 相关阅读:
    mongodb 简单的更新语句
    centos 安装ffmpeg 及h264编码打包
    mongodb $where查询
    javascript 上传进度条
    javascript 仿豆瓣读书笔记
    js监听浏览器剪贴板
    ffmpeg相关操作
    ffmpeg未整理好,有时间整理下
    fffmpeg 提取pcm
    ffmpeg转MP4 moov头在前命令
  • 原文地址:https://www.cnblogs.com/Onlymyheart/p/11235285.html
Copyright © 2011-2022 走看看