NOI模拟赛(3.15) sequence(序列)
Description
两个子序列被认为是不同的当且仅当:两个子序列属于两个不同的写序列方案(两个写序列方案中有至少一步是不一样的)或两个子序列位于同一写序列方案的不同位置。
由于结果可能很大,所以小A只需要知道最长严格上升子序列的方案数对10^9+7取模的结果。
Input
第二行包含N个由空格隔开的正整数,表示小A写下的初始序列。序列中的每一个元素小于等于10^9。
Output
Sample Input
输入1:
2
1 1
输入2:
4
2 1 3 4
Sample Output
输出1:
1 4
输出2:
4 1
Data Constraint
50%的数据满足:N<=1000
Solution
题目有一个隐藏性质是这样的
答案的第一问是对于每个点为结束点或开始点求出的最长上升序列长度和最长下降序列长度之和
在dp以上两个值的过程中同时统计方案数,用树状数组可以n log n时间复杂度做到
#include <vector>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define set_file(File) freopen(#File".in", "r", stdin), freopen(#File".out", "w", stdout)
#define close_file() fclose(stdin), fclose(stdout)
#define ll long long
#define mo 1000000007
#define maxn 200010 template<class T> inline void Rin(T &x)
{
int c = getchar();
for(x = 0; c < 48 || c > 57; c = getchar());
for(; c > 47 && c < 58; c = getchar()) x = (x << 1) + (x << 3) + c - 48;
} std::vector<int> VeH; int n, seq[maxn], mx[maxn], c[maxn], f[maxn], fs[maxn], g[maxn], gs[maxn]; void get_ans_lef(int i)
{
int x = seq[i] - 1, tot = 1, ans = 0;
for(; x; x -= x & -x)
{
if(mx[x] > ans) ans = mx[x], tot = c[x];
else if(mx[x] == ans) tot = (tot + c[x]) % mo;
}
f[i] = ans + 1, fs[i] = tot;
x = seq[i];
for(; x <= n; x += x & -x)
{
if(mx[x] < f[i]) mx[x] = f[i], c[x] = fs[i];
else if(mx[x] == f[i]) c[x] = (c[x] + fs[i]) % mo;
}
} void get_ans_rig(int i)
{
int x = seq[i] - 1, tot = 1, ans = 0;
for(; x; x -= x & -x)
{
if(mx[x] > ans) ans = mx[x], tot = c[x];
else if(mx[x] == ans) tot = (tot + c[x]) % mo;
}
g[i] = ans + 1, gs[i] = tot;
x = seq[i];
for(; x <= n; x += x & -x)
{
if(mx[x] < g[i]) mx[x] = g[i], c[x] = gs[i];
else if(mx[x] == g[i]) c[x] = (c[x] + gs[i]) % mo;
}
} int main()
{
set_file(sequence);
Rin(n);
for(int i = n; i; i--)
{
Rin(seq[i]);
VeH.push_back(seq[i]);
}
std::sort(VeH.begin(), VeH.end());
VeH.erase(unique(VeH.begin(), VeH.end()), VeH.end());
for(int i = 1; i <= n; i++) seq[i] = std::lower_bound(VeH.begin(), VeH.end(), seq[i]) - VeH.begin() + 1;
for(int i = 1; i <= n; i++) get_ans_lef(i);
memset(mx, 0, sizeof mx);
memset(c, 0, sizeof c);
for(int i = 1; i <= n; i++) seq[i] = n - seq[i] + 1;
for(int i = 1; i <= n; i++) get_ans_rig(i);
int tot = 0, ans = 0;
for(int i = 1; i <= n; i++)
if(f[i] + g[i] - 1 > ans) ans = f[i] + g[i] - 1, tot = (ll)fs[i] * gs[i] % mo;
else if(f[i] + g[i] - 1 == ans) tot = (tot + (ll)fs[i] * gs[i] % mo) % mo;
for(int i = 1; i <= n - ans; i++) tot = (ll)tot * 2 % mo;
printf("%d %d\n", ans, tot);
close_file();
return 0;
}
NOI模拟赛(3.15) sequence(序列)的更多相关文章
- Java 第十一届 蓝桥杯 省模拟赛 正整数的摆动序列
正整数的摆动序列 问题描述 如果一个序列的奇数项都比前一项大,偶数项都比前一项小,则称为一个摆动序列.即 a[2i]<a[2i-1], a[2i+1]>a[2i]. 小明想知道,长度为 m ...
- 6.28 NOI模拟赛 好题 状压dp 随机化
算是一道比较新颖的题目 尽管好像是两年前的省选模拟赛题目.. 对于20%的分数 可以进行爆搜,对于另外20%的数据 因为k很小所以考虑上状压dp. 观察最后答案是一个连通块 从而可以发现这个连通块必然 ...
- NOI模拟赛 Day1
[考完试不想说话系列] 他们都会做呢QAQ 我毛线也不会呢QAQ 悲伤ING 考试问题: 1.感觉不是很清醒,有点困╯﹏╰ 2.为啥总不按照计划来!!! 3.脑洞在哪里 4.把模拟赛当作真正的比赛,紧 ...
- NOI.ac模拟赛20181021 ball sequence color
T1 ball 可以发现每次推动球时,是将每个球的位置 −1-1−1 ,然后把最左边的球放到 P−1P-1P−1 处. 记个 −1-1−1 次数,再用set维护就好了. #include <bi ...
- NOI 模拟赛 #2
得分非常惨惨,半个小时写的纯暴力 70 分竟然拿了 rank 1... 如果 OYJason 和 wxjor 在可能会被爆踩吧 嘤 T1 欧拉子图 给一个无向图,如果一个边集的导出子图是一个欧拉回路, ...
- 【NOI模拟赛(湖南)】DeepDarkFantasy
DeepDarkFantasy 从东京出发,不久便到一处驿站,写道:日暮里. ——鲁迅<藤野先生> 定义一个置换的平方为对1~n的序列做两次该置换得到的序列.已知一个置换的平方,并且这个 ...
- [模拟赛] T3 最优序列
Description 给出一个长度为n(n<=1000)的正整数序列,求一个子序列,使得原序列中任意长度为m的子串中被选出的元素不超过k(k<=m<=10)个,并且选出的元素之和最 ...
- NOI模拟赛 #4
好像只有一个串串题可以做... 不会 dp 和数据结构啊 QAQ 10 + 20 + 100 = 130 T1 一棵树,每个点有一个能量的最大容量 $l_i$ 和一个增长速度 $v_i$,每次可以选一 ...
- NOI 模拟赛 #3
打开题一看,咦,两道数数,一道猫式树题 感觉树题不可做呀,暴力走人 数数题数哪个呢?感觉置换比矩阵好一些 于是数了数第一题 100 + 0 + 15 = 115 T1 bishop 给若干个环,这些环 ...
随机推荐
- Oracle 单引号与双引号的区别
双引号一般是用来转义的,如果alias里面有空格或其它保留符号,必须使用双引号.而单引号是用来特制的,比如字符串的引用,日期字符串的引用,都必须包括在单引号中,可以参与运算或其它表达式中.两者不可混用 ...
- AJPFX总结string类和简单问题
String表示字符串,所谓字符串,就是一连串的字符;String是不可变类,一旦String对象被创建,包含在对象中的字符序列(内容)是不可变的,直到对象被销毁://一个String对象的内容不能变 ...
- AJPFX的反射学习笔记
反射是描述 数据结构的结构 属性.方法(数据)元数据 类(数据结构)描述数据的结构-->类也是特殊的对象---->元数据 CLASS类 描述数据结 ...
- ubuntu安装mysql多实例
想要尝试mysql的读写分离,在云上安装完mysql之后突然想到一个问题:我本机是没有公网IP的. 开始尝试在唯一一台云服务器上安装多个mysql实例. 主要步骤: 1.新建MySQL目录 (1):新 ...
- CF962D Merge Equals
思路: 不必每次都找最小的值进行合并,从前往后扫一遍的过程中能合并就一直合并. 实现: #include <bits/stdc++.h> using namespace std; type ...
- cordova安装方法
安装cordova之前需要先安装node.js和npm 然后在命令行运行:npm install -g cordova即可安装到最新版本的cordova 如果要安装指定版本,命令为:npm insta ...
- RecycleView的万能适配器
转载自http://www.cnblogs.com/liushilin/p/5720926.html 由于RecyclerView的Adapter必须继承自RecyclerView.Adapter,并 ...
- ICEcoder显示汉字出现乱码的处理
在网上看到icecoder这个小东西,是一个基于web的编辑器,很不错.唯一的缺点是打开的文件中汉字会变成乱码. 经查看源代码,在lib/file-control.php中,第89行是: echo ' ...
- 微信小程序开发系列七:微信小程序的页面跳转
微信小程序开发系列教程 微信小程序开发系列一:微信小程序的申请和开发环境的搭建 微信小程序开发系列二:微信小程序的视图设计 微信小程序开发系列三:微信小程序的调试方法 微信小程序开发系列四:微信小程序 ...
- 阿里云服务器ECS部署应用教程
购买阿里云服务器 大多数云服务器默认安装的语言运行环境版本都很旧了,python用的还是2.7,JDK用的还是1.6的,在ECS云服务器中可以自行安装,包括python3.4之类的. 在次页面购买EC ...