首页 > 其他分享 >Day5

Day5

时间:2023-07-28 18:46:12浏览次数:30  
标签:那么 log 复杂度 Day5 矩阵 枚举 dp

Day 5

模拟赛

T1

设 \(dp_{i, j, k, 0/1}\)表示走到第 \(i, j\) 个格子,前面异或和为 \(k\) 的方案数

\(0 / 1\) 表示前面的每个路径丢了 \(/\) 没丢

转移方程:

\(f_{i,j,k,0} = f_{i-1,j,a_{i,j} \oplus k,0} + f_{i,j - 1,a_{i,j} \oplus k,0} + f_{i-1,j,k,1} + f_{i,j-1,k,1}\)

\(f_{i,j,k,1} = f_{i-1,j,a_{i,j} \oplus k,1} + f_{i,j - 1,a_{i,j} \oplus k,1}\)

\(O(mna)\)

code:

#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define gt getchar
using namespace std;
inline ll read(){
    ll x=0,f=1;char ch=gt();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=gt();}
    while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=gt();}
    return x*f;}
const int p = 998244353;
long long n, m, a[305][305], f[305][305][257][2];
int main()
{
    n = read(), m = read();
    for(int i = 1; i <= n; ++ i)
    {
        for(int j = 1; j <= m; ++ j)
        {
            cin >> a[i][j];
        }
    }
    f[1][1][0][0] = 1;
    f[1][1][a[1][1]][1] = 1;
    for(int i = 1; i <= n; ++ i)
        for(int j = 1; j <= m; ++ j)
            for(int k = 0; k <= 127; ++ k)
            {
                if(i == j && j == 1)continue;
                f[i][j][k][0] = ((f[i - 1][j][a[i][j] ^ k][0] + f[i][j - 1][a[i][j] ^ k][0]) % p+ f[i - 1][j][k][1] + f[i][j - 1][k][1]) % p;
                f[i][j][k][1] = (f[i - 1][j][a[i][j] ^ k][1] + f[i][j - 1][a[i][j] ^ k][1]) % p;
            }
    ll ans  = 0;
    for(int i = 0; i <= 127; ++ i)ans += i * f[n][m][i][0] % p, ans = ans % p;
    cout << ans;
    return 0;
}

T2

考虑将一条合法的路径在 LCA 处计算进答案。可以设 \(f_{i,j}\) 表示 \(i\)子树内一条祖先-儿子链,且祖先 > 儿子,最后一个点是 \(j\) 的方案数,\(g_{i,j}\) 则是祖先 < 儿子,最后一个点是 \(j\) 的方案数。

当 \(u\) 合并一颗子树 \(v\) 的时候,答案会增加

\(ad\sum_{a < b}f_{u,a} \times g_{v, b} + f_{u,b} \times g_{v, a}\)

时间复杂度 \(O(n^2)\)

code

?

T3

见数位dp

T4

见决策单调性

区间DP

朋友

有 \(n\) 个房间,\(m\) 个人。第 \(i\) 个人能进入第 \([li, ri]\) 个房间。

若最终一个房间里有 \(x\) 个人,则这个房间会有 \(x\) 的快乐值。

问最大的快乐值是多少。

\(n ≤ 300\)

可以证明,最优的答案存在一个房间,使得这个房间的人最多,且能到这个房间的人全部来了。

因为对于任何一个最大值,有个人没来,那么这个人到这里来之后一定会使答案增大。

所以设 \(f_{i,j}\) 表示只考虑只能到区间 \([i, j]\) 里面的人,最大的快乐值是什么。

枚举最大值在 \(k\),那么 \(f_{i,j} = \max f_{i,k−1} + f_{k+1,j} + v\)

其中 \(v\) 表示这里面能到 \(k\) 的人。

\(v\) 不太好求,正难则反,考虑不能 到 \(k\) 的人,他们的区间一定在 \([i, k - 1]\) 或 \([k + 1,j]\) 里

减去即可

复杂度 \(O(n ^ 2)\)

AGC033D

定义一个矩阵的凌乱度是:

如果这个矩阵字符全部相等,那么是 \(0\);

否则将这个矩阵切一刀,得到两个矩阵的凌乱度 \((a, b)\),对所有

\(\max(a, b) + 1\) 求最小值就是这个矩阵的凌乱度。

现在给定一个 \(n \times m\) 的矩阵,求它的凌乱度。

\(n, m ≤ 185\)

最暴力的 dp:设 \(f_{i,j,k,l}\) 表示左上角 \((i, j)\),右下角 \((k, l)\) 的矩阵

的凌乱度,那么转移直接枚举切了哪一刀就行。

时间复杂度 \(O(n^5)\) 优化可以做到 \(O(n^4)\) 很难通过。

但是可以注意到,\(f_{i,j,k,l}\) 会很小:

具体地,若区间长或宽不等于 \(1\),则可以将它对半切开

这样的答案即是 \(\log n + \log m\)

所以上面 \(f_{i,j,k,l}\) 的状态有很多其实是浪费(重复)的

因为它们的 dp 值一样。

显然 \(i, j, k\) 不变,\(f_{i, j, k, l}\) 不随 \(l\) 增大减小

所以设 \(g_{i, j, k}\) 表示最大的 \(l\) 使得 \(f_{i, j, k, l} < l\)

状态数 \(O(n^3logn)\)

考虑转移:

若横切,则贪心使上下都尽可能多,

则上面切到 \(p = g_{t -1, i, j, k}\) 下面切到 \(g_{t-1,i,p+1,k}\)

此为横切最小凌乱度

若竖切,则枚举切在 \(x\) 右边

则 \(g_{t,i,j,k} = \max\min(g_{t-1,i,j,x}, g_{t-1,x+1,j,k})\)

但仍无法通过

可以发现,随 \(x\) 增大,\(g_{t-1,i,j,x}\) 增大, \(g_{t-1,x + 1,j,k}\)减小

所以找最大的 \(x\) 使 \(g_{t-1,i,j,x} < g_{t-1,x + 1,j,k}\) 算在 \(x\) 还是在 \(x + 1\) 右边切更优

利用单调性找 \(x\):当 \(i, j\) 不变时,若 \(k\) 变成 \(k+1\)

则刚刚找到的 \(x,g_{t−1,i,j,x}\) 不变,\(g_{t−1,x+1,j,k}\) 可能变大。

所以当 \(k\) 变大时,\(x\) 也会跟着变大。

双指针,枚举 \(k\) 的同时,维护\(x\) 即可。

时间复杂度 \(O(n^3\log n)\)

数位DP

Luogu P9387

给定 \(n, m\),设 \(x = 1 ⊕ 2 ⊕ · · · ⊕ n − 1 ⊕ n ⊕ m\)

求有多少组 \((a, b, c)\),满足 \(a + b + c ≤ n\) 或 \(a + b + c = m\),

且 \((a + b + c) ⊕ a ⊕ c = x, b > 0,\) 对 \(10^9 + 7\) 取模。

(如果 \(a + b + c\) 既比 \(n\) 小也等于 \(m\),那么需要算两次)

\(n, m ≤ 10^{18}\),多组数据,每组数据要求复杂度 \(O(log n)\)。

T3

先不管 \(a + b + c = m\),会了 \(a + b + c ≤ n\) 自然就能得到

\(a + b + c = m\) 的方案数。

可以从低到高进行 dp,设 \(f_{i,j,0/1,0/1}\) 表示从低到高 dp 完前 \(i\) 位,

向第 \(i + 1\) 位进位的个数使 \(j,b\) 是否大于 \(0\),\(a + b + c\) 的低 \(i\) 位

是否大于 \(n\)。转移暴力枚举 \(a, b, c\) 的低 \(i\) 位是什么就行,最后答

案是 \(f_{60,0,1,0}\)。

单组时间复杂度 \(O(\log n)\)。

可以类似上面的题,但由于要算和

所以分别要记 \(f_{i,j}\) 表示所有

数确定完低 \(i\) 位,且低 \(i\) 位的和等于 \(m\) 的低 \(i\) 位的方案数,

\(g_{i,j}\)表示所有合法方案中的异或和。

转移的话,\(f_{i,j}\) 直接枚举第 \(i + 1\) 位有几个 \(1\),设为 \(x\),

然后只要 \(x + j\) 的奇偶性和 \(m\) 第 \(i + 1\) 位一样就行。

\(g_{i,j}\) 有两个部分的贡献:

一个是低于 \(i + 1\) 位的贡献,一个是第 \(i + 1\) 位的贡献。

分别算即可。即

\(g_{i, j} \times \binom{n}{x} + 2 ^ {i + 1} \times \binom{n}{x}\)

时间复杂度 \(O(n ^ 2\log m)\)

决策单调性

T4

首先,假设当我们已经选好了每个点的标准,那么每个人就一定会贪心地去他所能到达的店中标准最高的。

那么,跟刚刚的题一样,仍然可以枚举这个区间的最大值

即设 \(f_{i,j}\) 表示只考虑区间 \([i, j]\) 里的人的最大收益

然后枚举标准最高的点 \(k\),设能到达 \(k\) 的人有 \(t\) 个,

那么就是 \(f_{i,k}−1 + f_{j,k+1} + g_{k,t}\)

其中 \(g_{k,t}\) 表示有 \(t\) 个人到第 \(k\) 家店,合理选择标准能达到的最高收益

那么接下来就是求出所有 \(g_{k,t}\)。

由于每个人都求这个(过程一样),

于是下面用 \(c_i\) 代表标准为 \(i\) 的花费,\(f_j\) 表示有 \(j\) 个人来的最高收益

显然 \(f_j = \max i × j − c_i\)。

这个是一个标准的斜率优化式子,建出凸包来即可。

但是斜率优化是有限制的,比如这些都是能放在平面直角坐标系

上面的直线(也就是说贡献都可以写成 \(kx + b\))的形式。

有一种通用性更高,且理解起来并不比斜率优化复杂的决策单调性优化方法

对于一个 \(j\),假设 \(i_1 < i_2\),且这个时候选 \(i_2\) 比 \(i_1\) 更加优秀,

那么对于所有 \(k > j\),\(i_2\) 都会比 \(i_1\) 优秀,那么 \(i_1\) 在这之后就没有用了。

按 \(i\) 从小到大的顺序加入 \(i × j − c_i\) 这条直线。

假设已经处理完了之前的所有直线,那么对于所有可能成为最优选择的

\(i_1 < i_2 < · · ·i_k\),一定有 \(i_x\) 是 \(i_{x−1}\) 后面一些点的最优解。

我们对每个 \(i_x\) 记录 \(p_x\) 表示对于 \(j < p_x\),\(i_x\) 比 \(i_{x+1}\) 优,

之后则是 \(i_{x+1}\) 优,那么显然 \(p_1 < p_2 < · · · p_{k−1}\)。

否则若 \(p_x > p_{x+1}\),那么在 \(i_{x+1}\) 比 \(i_x\) 优之前,\(i_{x+2}\)

就已经比 \(i_{x+1}\) 优了,所以 \(i_{x+1}\) 就不可能成为最优选择了。

那么加入 \(i\) 的时候,先算出来 \(i\) 比 \(i_k\) 什么时候优(因为 \(i > i_k\),所以一定有个时间更优)

设为 \(y\),那么如果 \(x_k−1 > y\),那么根据上面 \(p_x\) 单调的解释,

就需要删除 \(i_k\),那么这样做就能维护出对于所有 \(j\),什么 \(i\) 最优。

做完这个之后直接枚举 $ j$,然后双指针不断从前往后扫到最后一个 \(p_x < j\) 的 \(x\),\(i_x+1\) 就是最优的答案。

这样的时间复杂度是线性。于是,整个题时间复杂度 \(O(n^3 + nk)\)

标签:那么,log,复杂度,Day5,矩阵,枚举,dp
From: https://www.cnblogs.com/qinzh/p/17588659.html

相关文章

  • Day5.2 Shell编程教程 - 特殊变量表达式参数
    1.特殊变量表达式参数`$0``$n``$#``$*``$@``$?``$$``$!`2.示例脚本示例脚本-`special_variables.sh`3.执行示例脚本4.结论大树哥个人信息在Shell脚本中,特殊变量提供了对脚本执行过程和执行环境的访问。它们帮助我们在脚本中获取脚本自身的名称、获取命令行参数以及处理其......
  • DAY5
    堆上分配内存的相关函数进行动态内存分配时常用的库函数一:malloc函数函数定义:void*malloc(size_tsize)参数是在heap里分配的内存空间的字节数大小,数据类型是size_t(正整数)例:表示在堆上请求四个字节,我们把malloc返回的地址存入void指针变量void*p=malloc(4);......
  • Python基础day54 Django2
    配置文件的介绍#注册应用的INSTALLED_APPS=['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.......
  • Python基础day53 Django
    web应用的简介因为Django框架是一个专门用来开发web项目的框架1.web应用程序是什么?web应用程序是一种可以通过web访问的应用程序,也就是说只需要一个浏览器即可,不需要其他软件了2.应用程序与有两种模式Django就是开发的B/S应用程序,所以,我们就认为浏览器就是我们......
  • Python基础day50
    RegExp对象//在JS中使用正则表达式,在js中如何使用正则呢?//定义正则表达式两种方式varreg1=newRegExp("^[a-zA-Z][a-zA-Z0-9]{5,11}");//第一种定义方式varreg2=/^[a-zA-Z][a-zA-Z0-9]{5,11}///第二种定义方式//正则校验数据varres=reg2.test('jason666......
  • week4 day5
    方法也可以抽象 具有抽象方法的类必须是抽象类 抽像的方法必须实现在继承树结构下的第一个具体类必须实现出所有的抽象方法复习一下方法重载:名称相同但是参数不同:1返回类型可以不同2不能只改变返回类型3可以更改存取权限publicintaddnums(inta,intb)puibicdoub......
  • 你省(福建)省队集训 Day5 T1 题解
    简要题意有两个正整数\(a<b\le10^9\),给出\(\dfrac{a}{b}\)的小数点后\(19\)位,要求还原\(a,b\),保证有解。solution一个科技:\(\texttt{Stern-Brocottree}(SBT)\),可以参考这个博客学习。先给出\(O(n)\)找的代码:......
  • day5
    一、[闽盾杯2021]DNS协议分析1.打开流量,过滤dns类型,发现一些类似于base64的编码,并且有规律的出现2.全部提取,ZmxhZ3tlNjYyYWMxNTRjYTM3NmUxYzAwMWVlOGJiZTgxMzE4Yn0K,base64在线解码二、云1.1.1得到一个URL,进去后界面显示一个hint的链接1.2告诉我们整体是一个SpringBoot......
  • 2022 省队二轮集训培训日记-Day5
    模拟赛T1非常简单的构造,但是我忘了判断$m=2$和对只有一个点特判的输出错误,导致挂成$20$。具体思路,考虑欧拉路径只能有两个奇点,但是每条边上中间的都是奇点,所以我们需要删掉边缘的一些边,直到剩下两个奇点,然后对于$n,m$都是偶数,或者一个偶数一个奇数,或者两个都是奇数来分别......
  • 你省(福建)省队集训 Day5 T3 乱搞分析
    简要题意有\(1\leT\le10^6\)次询问,每次询问正整数\(x,p\),\(p\)为素数,令\(n=xp^2\),问是否存在三个正整数\(a,b,c\),满足\(ab+bc+ca=n\)。有的话给出构造,否则输出\(-1\)。solution打表注意到只有\(n=4,18\)是无解的。打表namespaceDB{ constintN=1e5; struc......