[poj3378] Crazy Thairs (DP + 树状数组维护 + 高精度)
树状数组维护DP + 高精度
Description
These days, Sempr is crazed on one problem named Crazy Thair. Given N (1 ≤ N ≤ 50000) numbers, which are no more than 109, Crazy Thair is a group of 5 numbers {i, j, k, l, m} satisfying:
- 1 ≤ i < j < k < l < m ≤ N
- Ai < Aj < Ak < Al < Am
For example, in the sequence {2, 1, 3, 4, 5, 7, 6},there are four Crazy Thair groups: {1, 3, 4, 5, 6}, {2, 3, 4, 5, 6}, {1, 3, 4, 5, 7} and {2, 3, 4, 5, 7}.
Could you help Sempr to count how many Crazy Thairs in the sequence?
Input
Input contains several test cases. Each test case begins with a line containing a number N, followed by a line containing N numbers.
Output
Output the amount of Crazy Thairs in each sequence.
Sample Input
5
1 2 3 4 5
7
2 1 3 4 5 7 6
7
1 2 3 4 5 6 7
Sample Output
1
4
21
题目大意
给你一个长度为 n 的序列,输出长度为5
的上升子序列的个数。
题解
拿到这道题,可以很快的想出dp定义,
dp[i][j] 表示以 j 这个数结尾能组成长度为 i 的上升子序列的个数。可以推出转移方程为
\(dp[i][j] = \sum_{k=1}^{j-1}dp[i-1][k]\)
i 最大为5 ,j可以达到\(10^9\),但个数只有\(10^5\),所以我们可以考虑将 j 离散化,开 5 个树状数组来维护。
最后,这道题最坑的是,答案可能非常大,需要高精度。。。
代码
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
#define lowbit(x) (x & -x)
#define base 10000
const int maxn = 5e4 + 5;
int n;
int a[maxn];
vector <int> v;
struct Bign {
int c[20],l;
Bign() {memset(c,0,sizeof(c));l = 1;}
void reset() {memset(c,0,sizeof(c));l = 1;}
void Print() {
printf("%d",c[l]);
for(int i = l - 1;i > 0;i--)printf("%04d",c[i]);
}
void operator = (const int &a) {
int x = a;
reset();
c[1] = x % base;x /= base;
while(x) {
c[++l] = x % base;x /= base;
}
}
Bign operator + (const Bign &a) {
Bign res;
res.l = max(l,a.l);
for(int i = 1;i <= res.l;i++) {
res.c[i] += c[i] + a.c[i];
res.c[i+1] = res.c[i] / base;
res.c[i] %= base;
}
if(res.c[res.l+1])res.l++;
return res;
}
Bign operator += (const Bign &a) {
*this = *this + a;
return *this;
}
}t[5][maxn];
inline int getid(int x) {return lower_bound(v.begin(),v.end(),x) - v.begin() + 1;}
inline void update(int pos,int x,Bign a) {
while (x <= n) {
t[pos][x] += a;
x += lowbit(x);
}
}
inline Bign query(int pos,int x) {
Bign res;
while(x) {
res += t[pos][x];
x -= lowbit(x);
}
return res;
}
int main() {
ios::sync_with_stdio(false);cin.tie(0);
while(cin >> n) {
v.clear();
for(int i = 0;i < n;i++) {
cin >> a[i];v.push_back(a[i]);
}
Bign ans;
sort(v.begin(),v.end());v.erase(unique(v.begin(),v.end()),v.end());
memset(t,0,sizeof(t));
for(int i = 0;i < n;i++) {
int x = getid(a[i]);
Bign xx;xx = 1;
update(0,x,xx);
for(int i = 1;i < 5;i++) {
update(i,x,query(i-1,x-1));
}
}
ans = query(4,n);
ans.Print();printf("\n");
}
return 0;
}
[poj3378] Crazy Thairs (DP + 树状数组维护 + 高精度)的更多相关文章
- 【POJ】3378 Crazy Thairs(树状数组+dp+高精)
题目 传送门:QWQ 分析 题意:给个数列,求有多少五元上升组 考虑简化一下问题:如果题目求二元上升组怎么做. 仿照一下逆序对,用树状数组维护一下就ok了. 三元怎么做呢? 把二元的拓展一位就可以了, ...
- POJ 3378 Crazy Thairs(树状数组+DP)
[题目链接] http://poj.org/problem?id=3378 [题目大意] 给出一个序列,求序列中长度等于5的LIS数量. [题解] 我们发现对于每个数长度为k的LIS有dp[k][i] ...
- HDU 2838 (DP+树状数组维护带权排序)
Reference: http://blog.csdn.net/me4546/article/details/6333225 题目链接: http://acm.hdu.edu.cn/showprobl ...
- P1020 导弹拦截 dp 树状数组维护最长升序列
题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某天,雷达捕捉到敌国的导弹 ...
- bzoj 3594: [Scoi2014]方伯伯的玉米田 dp树状数组优化
3594: [Scoi2014]方伯伯的玉米田 Time Limit: 60 Sec Memory Limit: 128 MBSubmit: 314 Solved: 132[Submit][Sta ...
- URAL1523(dp+树状数组)
题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=41224#problem/B 分析:可以设dp[i][j]表示以i结尾长度为j的 ...
- Gym - 100269F Flight Boarding Optimization(dp+树状数组)
原题链接 题意: 现在有n个人,s个位置和你可以划分长k个区域你可以把s个位置划分成k个区域,这样每个人坐下你的代价是该区域内,在你之前比你小的人的数量问你怎么划分这s个位置(当然,每个区域必须是连续 ...
- bzoj 1264 [AHOI2006]基因匹配Match dp + 树状数组
思路:好难想啊, 考虑到应该从每个数字只有5个数字下手, 但是不知道到底该怎么写.. 首先我们将第一个串按数字的种类分类, 每一类里面有5个, 然后将第二个串里面的数字一个一个加,如果一个加入的第 i ...
- Codeforces 1085G(1086E) Beautiful Matrix $dp$+树状数组
题意 定义一个\(n*n\)的矩阵是\(beautiful\)的,需要满足以下三个条件: 1.每一行是一个排列. 2.上下相邻的两个元素的值不同. 再定义两个矩阵的字典序大的矩阵大(从左往右从上到下一 ...
随机推荐
- 最轻量级的前端Mvc框架backbone
最轻量级的前端Mvc框架backbone依赖最轻量级的库understore backbone并非将前端再次切分为mvc,而是分为了七大模块,分别是:Events.Model.Collection.R ...
- sprintf的缓冲区溢出问题
因为sprintf函数没有参数指定缓冲区的大小,这使得溢出的可能性很大,尤其是遇到 sprintf( buffer, "%s", a ) 如果不知道a的串长,就无法指定安全的缓冲区 ...
- 关闭SSMS的事务自动提交,改为手动提交
SQLServer 2005-2008-2012使用Oracle时,默认是手动提交.而SQLServer2005中,默认是自动提交,但是SQLServer支持配置. 方法: 用SSMS连接到SQL S ...
- Android课程---视图组件总结
- 数位dp/记忆化搜索
一.引例 #1033 : 交错和 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 给定一个数 x,设它十进制展从高位到低位上的数位依次是 a0, a1, ..., an ...
- SharePoint 2013 网站应用程序、网站集、网站知识整理
网站应用程序:Web 应用程序是一种可以通过Web访问的应用程序.我们自己以前用VS开发的Web应用程序一般是通过人工部署到IIS上的,而SharePoint的Web应用程序是由SharePoint安 ...
- 优秀API设计的十大原则
优秀API设计的十大原则 2015-09-23 分类:编程开发.设计模式.首页精华暂无人评论 分享到:更多4 二十万年薪PHP工程师培养计划 成为被疯抢的Android牛人 风中叶讲Java重难 ...
- fuelux.tree用法
ACE中带了一个树,样式和操作挺好看的,就是难用,下面记录下如何使用. 首先fuelux.tree接受的数据源是Json,关键这个Json还不怎么标准,可接受的Json示例如下: { '刑侦': { ...
- Bootstrap Typeahead/Jquery autocomplete自动补全
使用Bootstrap Typeahead 组件: Bootstrap 中的 Typeahead 组件就是通常所说的自动完成 AutoComplete,自动填充. 效果如图所示: 实现方式: 1.引入 ...
- C++ 中的类构造函数 & 析构函数
类的构造函数 类的构造函数是类的一种特殊的成员函数,它会在每次创建类的新对象时执行. 构造函数的名称与类的名称是完全相同的,并且不会返回任何类型,也不会返回 void.构造函数可用于为某些成员变量设置 ...