2017 多校4 Wavel Sequence
2017 多校4 Wavel Sequence
题意:
Formally, he defines a sequence \(a_1,a_2,...,a_n\) as ''wavel'' if and only if \(a_1<a_2>a_3<a_4>a_5<a_6\)...
Now given two sequences \(a_1,a_2,...,a_n\) and \(b_1,b_2,...,b_m\), Little Q wants to find two sequences \(f_1,f_2,...,f_k(1≤f_i≤n,f_i<f_{i+1})\) and \(g_1,g_2,...,g_k(1≤g_i≤m,g_i<g_i+1)\), where \(a_{f_i}=b_{g_i}\) always holds and sequence \(a_{f_1},a_{f_2},...,a_{f_k}\) is ''wavel''.
\(1<=n,m<=2000\)
\(1<=a_i,b_i<=2000\)
题解:
设\(f_{i,j,k}\)
表示仅考虑\(a[1..i]\)与\(b[1..j]\),选择的两个子序列结尾分别是\(a_i\)和\(b_j\),且上升下降状态是\(k\) 时的方案数,
则\(f_{i,j,k}=\sum f_{x,y,1-k}\)
,其中\(x<i,y<j\)
具体点说
定义\(f[i][j][0/1]\)为选择的两个子序列结尾分别是\(a_i\)和\(b_j\),当前为下降/上升状态的方案数
则当\(a[i] = b[j]\)的时候有
\(f[i][j][0] = \sum f[x][y][1]\),其中\(x < i,y < j 且a[x] < a[i]\)
\(f[i][j][1] = \sum f[x][y][0] + 1\),其中\(x < i,y < j 且a[x] > a[i]\)
暴力枚举是O(n^4)的,可以用二维树状数组去优化两维变成\(O(n^{2}log{^2}n)\)
顺序枚举i,保证了第一维递增的,只需要用树状数组去维护第二维的下标和值
#include<bits/stdc++.h>
#define LL long long
#define P pair<int,int>
using namespace std;
const int N = 2e3 + 10;
const int mod = 998244353;
int read(){
int x = 0;
char c = getchar();
while(c < '0' || c > '9') c = getchar();
while(c >= '0' && c <= '9') x = x * 10 + c - 48, c = getchar();
return x;
}
int s[2][N][N];
int a[N],b[N];
int n,m;
void add(int &x,int y){
x += y;
if(x >= mod) x -= mod;
}
int lowbit(int x){
return x & (-x);
}
int sum(int o,int i,int j){
int ans = 0;
while(i){
int y = j;
while(y){
add(ans,s[o][i][y]);
y -= lowbit(y);
}
i -= lowbit(i);
}
return ans;
}
void update(int o,int i,int j,int val){
while(i <= n){
int y = j;
while(y <= 2000){
add(s[o][i][y],val);
y += lowbit(y);
}
i += lowbit(i);
}
}
int main(){
int T;
T = read();
while(T--){
n = read(),m = read();
for(int k = 0;k < 2;k++)
for(int i = 1;i <= n;i++)
for(int j = 1;j <= 2000;j++) s[k][i][j] = 0;
for(int i = 1;i <= n;i++) a[i] = read();
for(int i = 1;i <= m;i++) b[i] = read();
int ans = 0;
for(int i = 1;i <= m;i++){
for(int j = 1;j <= n;j++){
if(b[i] == a[j]){
int tmp1 = sum(1,j-1,a[j]-1),tmp2 = (mod + sum(0,j-1,2000)-sum(0,j-1,a[j]))%mod;
update(0,j,a[j],tmp1);/// 0 下降 1 上升
update(1,j,a[j],(tmp2 + 1)%mod);
add(ans,tmp1);
add(ans,tmp2);
add(ans,1);
}
}
}
printf("%d\n",ans);
}
return 0;
}
题解的\(O(n^2)\)的做法
用\(s[i][j][0/1]\)表示\(a\)和\(b\)分别在\(1\)$i$和$1$\(j\)的结尾的子序列的方案
那么\(dp[i][j][k] = s[i-1][j-1][1 - k] + k==1?1:0\)
\(i,j\)顺序枚举,遇到\(a[i] = b[j]\)的时候,前面可以顺便计算大于和小于它的方案,然后更新即可
#include<bits/stdc++.h>
#define LL long long
#define P pair<int,int>
using namespace std;
const int N = 2e3 + 10;
const int mod = 998244353;
int read(){
int x = 0;
char c = getchar();
while(c < '0' || c > '9') c = getchar();
while(c >= '0' && c <= '9') x = x * 10 + c - 48, c = getchar();
return x;
}
int s[2][N][N];
int dp[2][N][N];
int a[N],b[N];
int n,m;
void add(int &x,int y){
x += y;
if(x >= mod) x -= mod;
}
int main(){
int T;
T = read();
while(T--){
n = read(),m = read();
for(int i = 1;i <= n;i++) a[i] = read();
for(int i = 1;i <= m;i++) b[i] = read();
for(int k = 0;k < 2;k++)
for(int i = 1;i <= n;i++)
for(int j = 1;j <= m;j++) dp[k][i][j] = s[k][i][j] = 0;
int ans = 0;
for(int i = 1;i <= n;i++){
int tmp0 = 0,tmp1 = 0;///0 下降 1 上升
for(int j = 1;j <= m;j++){
if(a[i] == b[j]){
add(dp[0][i][j],tmp0);
add(dp[1][i][j],(tmp1+1)%mod);
add(ans,(dp[0][i][j]+dp[1][i][j])%mod);
}
else if(a[i] > b[j]){
add(tmp0, s[1][i-1][j]);
}else{
add(tmp1,s[0][i-1][j]);
}
}
for(int j = 1;j <= m;j++){
s[0][i][j] = s[0][i-1][j];
s[1][i][j] = s[1][i-1][j];
if(a[i] == b[j]){
add(s[0][i][j],dp[0][i][j]);
add(s[1][i][j],dp[1][i][j]);
}
}
}
printf("%d\n",ans);
}
return 0;
}
2017 多校4 Wavel Sequence的更多相关文章
- HDU 6078 - Wavel Sequence | 2017 Multi-University Training Contest 4
/* HDU 6078 - Wavel Sequence [ DP ] | 2017 Multi-University Training Contest 4 题意: 给定 a[N], b[M] 要求满 ...
- hdu6078 Wavel Sequence dp+二维树状数组
//#pragma comment(linker, "/STACK:102400000,102400000") /** 题目:hdu6078 Wavel Sequence 链接:h ...
- 2017 多校5 hdu 6093 Rikka with Number
2017 多校5 Rikka with Number(数学 + 数位dp) 题意: 统计\([L,R]\)内 有多少数字 满足在某个\(d(d>=2)\)进制下是\(d\)的全排列的 \(1 & ...
- 2017 多校5 Rikka with String
2017 多校5 Rikka with String(ac自动机+dp) 题意: Yuta has \(n\) \(01\) strings \(s_i\), and he wants to know ...
- 2017 多校4 Security Check
2017 多校4 Security Check 题意: 有\(A_i\)和\(B_i\)两个长度为\(n\)的队列过安检,当\(|A_i-B_j|>K\)的时候, \(A_i和B_j\)是可以同 ...
- 2017 多校3 hdu 6061 RXD and functions
2017 多校3 hdu 6061 RXD and functions(FFT) 题意: 给一个函数\(f(x)=\sum_{i=0}^{n}c_i \cdot x^{i}\) 求\(g(x) = f ...
- 2017 多校2 hdu 6053 TrickGCD
2017 多校2 hdu 6053 TrickGCD 题目: You are given an array \(A\) , and Zhu wants to know there are how ma ...
- 2017 多校1 I Curse Myself
2017 多校2 I Curse Myself(第k小生成树) 题目: 给一张带权无向连通图,该图的任意一条边最多只会经过一个简单环,定义\(V(k)为第k小生成树的权值和\),求出\(\sum_{k ...
- hdu6136[模拟+优先队列] 2017多校8
有点麻烦.. /*hdu6136[模拟+优先队列] 2017多校8*/ #include <bits/stdc++.h> using namespace std; typedef long ...
随机推荐
- python基础——文件访问模式
文件访问模式 访问模式 说明 r 以只读方式打开文件.文件的指针将会放在文件的开头.这是默认模式. w 打开一个文件只用于写入.如果该文件已存在则将其覆盖.如果该文件不存在,创建新文件. a 打开一个 ...
- Linux文件系统与目录结构
在Linux系统中,目录被组织成一个:单根倒置树结构,文件系统从根目录开始,用/来表示.文件名称区分大小写( 大小写敏感还需要看具体的文件系统格式 ),以.开头的为隐藏文件,路径用/来进行分割(win ...
- C#基础-面向对象-多态
多态,不同对象对同一方法的不同实现 使用abstract关键字表示抽象类 // 表示是一个抽象类 public abstract class Animal { private string name; ...
- php集成开发环境xampp的搭建
一:运维闲谈 作为一名linux运维工程师,在确保能够有熟练的服务器的搭建和维护优化技能的前提,还需对自身解决问题方法上做出一番功夫. 如何为自己的运维工作添砖加瓦,自动化运维便变得非常重要,一方面, ...
- js面向(基于)对象编程—类(原型对象)与对象
JS分三个部分: 1. ECMAScript标准--基础语法 2. DOM Document Object Model 文档对象模型 3. BOM Browser Object Moldel 浏览 ...
- php扩展开发-资源类型
资源类型在内核中的结构 //zend_list.h typedef struct _zend_rsrc_list_entry { void *ptr; int type; int refcount; ...
- C语言进阶——循环语句07
循环语句的基本工作方式: 通过条件表达式判定是否执行循环体 条件表达式遵循if语句表达式的原则 do,while,for的区别: do语句先执行后判断,循环体至少执行一次 while语句先判断后执行, ...
- 3、springboot配置文件占位符
RandomValuePropertySource:配置文件中可以使用随机数 ${random.value}.${random.int}.${random.long}.${random.int(10) ...
- POJ:3190-Stall Reservations
传送门:http://poj.org/problem?id=3190 Stall Reservations Time Limit: 1000MS Memory Limit: 65536K Total ...
- 第一章:Hello, World!
感谢作者 –> 原文链接 本文翻译自The Flask Mega-Tutorial Part I: Hello, World! 一趟愉快的学习之旅即将开始,跟随它你将学会用Python和Flas ...