树状数组维护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. 1 ≤ i < j < k < l < m ≤ N
  2. 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 + 树状数组维护 + 高精度)的更多相关文章

  1. 【POJ】3378 Crazy Thairs(树状数组+dp+高精)

    题目 传送门:QWQ 分析 题意:给个数列,求有多少五元上升组 考虑简化一下问题:如果题目求二元上升组怎么做. 仿照一下逆序对,用树状数组维护一下就ok了. 三元怎么做呢? 把二元的拓展一位就可以了, ...

  2. POJ 3378 Crazy Thairs(树状数组+DP)

    [题目链接] http://poj.org/problem?id=3378 [题目大意] 给出一个序列,求序列中长度等于5的LIS数量. [题解] 我们发现对于每个数长度为k的LIS有dp[k][i] ...

  3. HDU 2838 (DP+树状数组维护带权排序)

    Reference: http://blog.csdn.net/me4546/article/details/6333225 题目链接: http://acm.hdu.edu.cn/showprobl ...

  4. P1020 导弹拦截 dp 树状数组维护最长升序列

    题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某天,雷达捕捉到敌国的导弹 ...

  5. bzoj 3594: [Scoi2014]方伯伯的玉米田 dp树状数组优化

    3594: [Scoi2014]方伯伯的玉米田 Time Limit: 60 Sec  Memory Limit: 128 MBSubmit: 314  Solved: 132[Submit][Sta ...

  6. URAL1523(dp+树状数组)

    题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=41224#problem/B 分析:可以设dp[i][j]表示以i结尾长度为j的 ...

  7. Gym - 100269F Flight Boarding Optimization(dp+树状数组)

    原题链接 题意: 现在有n个人,s个位置和你可以划分长k个区域你可以把s个位置划分成k个区域,这样每个人坐下你的代价是该区域内,在你之前比你小的人的数量问你怎么划分这s个位置(当然,每个区域必须是连续 ...

  8. bzoj 1264 [AHOI2006]基因匹配Match dp + 树状数组

    思路:好难想啊, 考虑到应该从每个数字只有5个数字下手, 但是不知道到底该怎么写.. 首先我们将第一个串按数字的种类分类, 每一类里面有5个, 然后将第二个串里面的数字一个一个加,如果一个加入的第 i ...

  9. Codeforces 1085G(1086E) Beautiful Matrix $dp$+树状数组

    题意 定义一个\(n*n\)的矩阵是\(beautiful\)的,需要满足以下三个条件: 1.每一行是一个排列. 2.上下相邻的两个元素的值不同. 再定义两个矩阵的字典序大的矩阵大(从左往右从上到下一 ...

随机推荐

  1. 最轻量级的前端Mvc框架backbone

    最轻量级的前端Mvc框架backbone依赖最轻量级的库understore backbone并非将前端再次切分为mvc,而是分为了七大模块,分别是:Events.Model.Collection.R ...

  2. sprintf的缓冲区溢出问题

    因为sprintf函数没有参数指定缓冲区的大小,这使得溢出的可能性很大,尤其是遇到 sprintf( buffer, "%s", a ) 如果不知道a的串长,就无法指定安全的缓冲区 ...

  3. 关闭SSMS的事务自动提交,改为手动提交

    SQLServer 2005-2008-2012使用Oracle时,默认是手动提交.而SQLServer2005中,默认是自动提交,但是SQLServer支持配置. 方法: 用SSMS连接到SQL S ...

  4. Android课程---视图组件总结

  5. 数位dp/记忆化搜索

    一.引例 #1033 : 交错和 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 给定一个数 x,设它十进制展从高位到低位上的数位依次是 a0, a1, ..., an  ...

  6. SharePoint 2013 网站应用程序、网站集、网站知识整理

    网站应用程序:Web 应用程序是一种可以通过Web访问的应用程序.我们自己以前用VS开发的Web应用程序一般是通过人工部署到IIS上的,而SharePoint的Web应用程序是由SharePoint安 ...

  7. 优秀API设计的十大原则

    优秀API设计的十大原则 2015-09-23    分类:编程开发.设计模式.首页精华暂无人评论 分享到:更多4 二十万年薪PHP工程师培养计划 成为被疯抢的Android牛人 风中叶讲Java重难 ...

  8. fuelux.tree用法

    ACE中带了一个树,样式和操作挺好看的,就是难用,下面记录下如何使用. 首先fuelux.tree接受的数据源是Json,关键这个Json还不怎么标准,可接受的Json示例如下: { '刑侦': { ...

  9. Bootstrap Typeahead/Jquery autocomplete自动补全

    使用Bootstrap Typeahead 组件: Bootstrap 中的 Typeahead 组件就是通常所说的自动完成 AutoComplete,自动填充. 效果如图所示: 实现方式: 1.引入 ...

  10. C++ 中的类构造函数 & 析构函数

    类的构造函数 类的构造函数是类的一种特殊的成员函数,它会在每次创建类的新对象时执行. 构造函数的名称与类的名称是完全相同的,并且不会返回任何类型,也不会返回 void.构造函数可用于为某些成员变量设置 ...