首页 > 其他分享 > 2022NOIP A层联测25 惊喜二十二 K-构造 函数的权力 最大可达流形

2022NOIP A层联测25 惊喜二十二 K-构造 函数的权力 最大可达流形

时间:2022-11-11 19:56:54浏览次数:48  
标签:25 ch int 2022NOIP long 联测 qi now mod

T1[计数类DP/转化]给出2个排列p,q,长度都是n,其中p完全给出,\(\exists pi=0 \Leftrightarrow i位置可以填任意[1,n]之间的数使得q构成排列\),问长度是n的01串S的个数,使得存在2*n的矩阵,满足\(a_{1,i}<a_{1,j}\Leftrightarrow pi<pj,a_{2,i}<a_{2,j}\Leftrightarrow qi<qj,si=0\Leftrightarrow a_{1,i}=a_{2,i}\)。(n<=100)

考场

没思路,发现枚举什么都会T飞,\(O(n!*2^n*n)\),然后发现对于qi=0的看起来就很随和,就蒙了一个\(2^n\),骗了5分

正解

套路性的思路转化,2个相对变化等价于只变化一个,所以sortp之后只需要考虑在a1升序下的满足条件,
偏序关系转化图论,发现1、2、3的条件使得矩形的任意上下点之间有边连接,定义\(ai>aj \Leftrightarrow edge(ai->aj)\),那么因为p顺序固定了,所以环(矛盾关系)方向固定了,所以矛盾当且仅当\(qi>qj,si=1,sj=0\).
抽象化s的含义,把10看成选或者不选,不合法序列就是\(\exists qi>qj,i和j都选择\),合法序列就是\(\forall i_{choose},j_{choose},qi<qj\),所以就是qi的上升子序列个数.
考虑没有空位只需要记录上一位最大,有就添加中间有多少已选择的未知
\(f[i][j]:前i个数,ai是上升序列最后一位,有j个选择的qj=0的位置\)
\(f[i][j]+=f[k][l]*C(val[i-k],j-l)*C(chose[i-k],j-l)\),表示从k-i的区间中填补上l个上升子序列,可以选择的数值是在[qk,qi]之间没出现的,可以选择的位置是[k,i]之间0的个数。
\(ans=\sum f[n][l]*A(chose_n-l)\),表示剩下的空位随便选择,全排列。

点击查看代码
// ubsan: undefined
// accoders
#include <bits/stdc++.h>
using namespace std;
#define chu printf
#define rint register int
#define ll long long
#define ull unsigned long long
inline ll re() {
    ll x = 0, h = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9') {
        if (ch == '-')
            h = -1;
        ch = getchar();
    }
    while (ch <= '9' && ch >= '0') {
        x = (x << 1) + (x << 3) + (ch ^ 48);
        ch = getchar();
    }
    return x * h;
}
const int N = 110;
const int mod = 998244353;
inline void upd(int& fg, int fp) {
    fg += fp;
    fg = (fg < 0) ? (fg + mod) : ((fg >= mod) ? (fg - mod) : fg);
}
int f[N][N], s[N], g[N], n, C[N][N];
int q[N], fac[N];
int chs[N];
struct node {
    int a, b;
    bool operator<(const node& U) const { return a < U.a; }
} p[N];
// f[i][j]:表示前i个数,有j个选择的不确定的位置的方案数
// s[i]:前i个位置有多少等着选择
// g[i]:前i个值有多少等着选择
int main() {
    // freopen("1.in","r",stdin);
    // freopen("1.out","w",stdout);
    freopen("surprise.in", "r", stdin);
    freopen("surprise.out", "w", stdout);
    n = re();
    for (rint i = 1; i <= n; ++i) p[i].a = re();
    for (rint i = 1; i <= n; ++i) p[i].b = re();
    sort(p + 1, p + 1 + n);
    for (rint i = 1; i <= n; ++i) q[i] = p[i].b;
    chs[++chs[0]] = 0;
    for (rint i = 1; i <= n; ++i) {
        // chu("q[%d]:%d\n",i,q[i]);
        if (q[i] == 0)
            s[i] = s[i - 1] + 1;
        else
            s[i] = s[i - 1];
        if (q[i])
            g[q[i]] = 1, chs[++chs[0]] = i;
    }
    s[n + 1] = s[n];
    q[n + 1] = n + 1;
    chs[++chs[0]] = n + 1;
    for (rint i = 1; i <= n; ++i) g[i] = g[i - 1] + (!g[i]);  //有的值不选择
    C[0][0] = 1;
    for (rint i = 1; i <= n; ++i) {
        // chu("q[%d]:%d\n",i,q[i]);
        C[i][0] = 1;
        for (rint j = 1; j <= i; ++j) upd(C[i][j], (1ll * (C[i - 1][j] + C[i - 1][j - 1]) % mod));
    }
    fac[0] = fac[1] = 1;
    for (rint i = 2; i <= n; ++i) fac[i] = 1ll * fac[i - 1] * i % mod;
    f[0][0] = 1;
    // chu("C[]:%d\n",C[5][2]);
    for (rint I = 2, i = chs[I]; I <= chs[0]; ++I, i = chs[I])  //枚举当前的有数的位置
    {
        for (rint j = 0; j <= s[i]; ++j)  //枚举当前选择j未知数
        {
            // chu("upd:f[%d][%d]\n",i,j);
            for (rint K = 1, k = chs[K]; K < I; ++K, k = chs[K])  //枚举从k位置转移
            {
                // chu("q[%d]:%d q[%d]:%d\n",i,q[i],k,q[k]);
                if (q[i] < q[k])
                    continue;
                for (rint l = 0; l <= min(j, s[k]); ++l)  //枚举上一个状态选择了l未知数
                {
                    //目前选了now个未知数
                    if (!f[k][l])
                        continue;
                    // chu("can from:%d %d:%d\n",k,l,f[k][l]);
                    int now = j - l;
                    if (s[i] - s[k] >= now && g[q[i] - 1] - g[q[k]] >= now)
                        upd(f[i][j], (1ll * f[k][l] * C[s[i] - s[k]][now] % mod *
                                      C[g[q[i] - 1] - g[q[k]]][now] % mod) %
                                         mod);
                }
            }
            // chu("f[%d][%d]:%d  * fac[%d]:%d\n",i,j,f[i][j],s[n]-j,fac[s[n]-j]);
        }
    }
    int ans = 0;
    for (rint i = 0; i <= s[n]; ++i) upd(ans, 1ll * f[n + 1][i] * fac[s[n] - i] % mod);
    chu("%d", ans);
    return 0;
}
/*
2
1 2
2 1
*/

标签:25,ch,int,2022NOIP,long,联测,qi,now,mod
From: https://www.cnblogs.com/403caorong/p/16881576.html

相关文章

  • NOIP联测25
    T1.将军棋其实挺水的一道题,但是出题人丧心病狂强迫分类讨论,故意增加码量。\(A\)挨着查直到队伍不同\(B、C\)记录每种颜色最后出现的位置,枚举是哪一种颜色。对于\(B\)......
  • 223201062522刘晋-软件工程基础Y- 实验二 结对项目报告
    沈阳航空航天大学软件工程基础实验报告实验名称:实验二实验题目:结对项目专业软件工程学号223201062522姓名刘晋结对伙伴赵德龙指导教师孟桂英......
  • 爬取豆瓣TOP250
    实验1基于多线程的静态网页爬取项目1.实验目的(1)熟悉网页浏览器开发工具的使用;(2)掌握网页爬取requests库的使用;(3)掌握网页解析技术,例如Xpath、BeautifulSoup、re等;(4)......
  • P2254 [NOI2005] 瑰丽华尔兹 题解
    注意到可以设朴素转移方程\(f_{t,i,j}\)表示\(t\)时刻钢琴在\((i,j)\)时的最长滑动距离,这样复杂度是\(O(nmt)\)的,过不去。不过听说加点奇怪的优化能过?考虑一段时......
  • Cinema 4D R2023.1(c4d r25 mac)
    Cinema4DR2023.1是Mac上知名的3D动画设计制作软件,包含GPU渲染器Prorender、生产级实时视窗着色、超强破碎、场景重建等诸多新功能,C4Dmac为用户提供高端的3D内容创建,......
  • 25、递归搜索目录找出最大的文件
    题目:  在变量名serach_dir中,随意添加一个文件路径,找出所有文件下最大的文件。思路:  1、输入文件路径。  2、递归遍历该文件路径下所有子目录。  3、遍历子目......
  • 【安装文档】TRex流量分析仪保姆级安装指南--基于VMware虚拟机(ubantu18.04@Intel 8254
    前言既然你已经知道TRex并尝试搜索它的安装教程,这意味着你有一定的基础知识(至少知道自己需要什么)。因此本文对于TRex的介绍部分会偏少本次主要为TRex安装过程的一次记录(......
  • IT25589: LIST HISTORY COMMAND FAILS WITH DB21018E ERROR WHEN THE HISTORY FILE CO
    KnownIssues https://www.ibm.com/mysupport/s/defect/aCI3p000000kF7p/dt159458?language=en_USIT25589:LISTHISTORYCOMMANDFAILSWITHDB21018EERRORW......
  • 25-jmeter-使用简单数据写入器保存测试结果
    前言jmeter做性能压测的时候,我们希望把每次的结果保存下来,方便写测试总结报告。可以用的监听器SimpleDataWriter,保存测试的结果简单数据写入SimpleDataWriter添加-......
  • 白嫖永久服务器1668060025667
    阿贝云服务器注册免费领取1核1g内存5m宽带10g内存的云服务器,对于个人来说完全够用了。还有免费备案和虚拟主机,免备案对于搭建个人博客就很方便,部署了小项目上去,运行流畅不......