这个题目很有意思,也是一个很好的题目,涉及的知识点比较广,要求较高。

题目是这样的,给定你一个n个数的数列,问你有多少个长度为5的上升序列。

首先看到有50000,我们就知道肯定不会是DP。(但是不知道为什么我居然在DP优化这个章节里面做到了这个题)

由于给的数是在int范围里面的,我们需要首先将其离散化,这样相当于每个数的范围只有5000了。

剩下的就是这个题目的最最精华的地方了。

其实这里的统计是用树状数组来实现的。但是不是单单由一个树状数组实现的,而是5个。

什么意思呢?我们用f[i][j]表示不大于j的长度为i的上升序列有多少个。

这样就是一个递推了哦。而对于每一个查询我们都是通过树状数组来实现的,每次查询前面每一个长度,然后加入当前这个数字,这样每次操作的时间复杂度都是O(n*log(n))。

这样答案就呼之欲出了。

但是,你确定?

自己算一下就会发现,如果给你的数为50000个上升的数字,你的程序就直接跪了。

什么意思呢?你可以算一算,C(50000,5)> 2^64,也就是说超过了long long的范围。

这个嘛,有点那个啥。

不过我们可以这样做,保存和更新的只需要是长度为4的有多少个,C(50000,4)是不会超的。这样对于最后一次加法,直接用一个高精度数组保存答案和输出就可以了。

代码如下:

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 50500
#define M 1000000000
using namespace std; typedef long long ll;
struct node{
ll num,pos;
}a[maxn]; struct big{
ll b[],top;
void Clear()
{
memset(b,,sizeof b);
top=;
}
void output()
{
printf("%I64d",b[top]);
for (ll i=top-; i>=; i--) printf("%09I64d",b[i]);
printf("\n");
}
void Add(ll x)
{
ll cur=;
while (x) b[cur++]+=x%M,x/=M;
for (ll i=; i<top; i++) b[i+]+=b[i]/M,b[i]%=M;
while (b[top]>=M) b[top+]+=b[top]/M,b[top]%=M,top++;
}
}ans; ll f[][maxn],g[maxn];
ll n,tep; bool cmp(node n1,node n2) { return n1.num<n2.num; } void rankthem()
{
ll cur=;
for (ll i=; i<=n; i++)
{
if (a[i].num!=a[i-].num) cur++;
g[a[i].pos]=cur;
}
} ll lowbit(ll x) { return x&(-x); } void add(ll u[],ll x,ll v) { while (x<maxn) u[x]+=v,x+=lowbit(x); } ll sum(ll u[],ll x)
{
ll tot=;
while (x) tot+=u[x],x-=lowbit(x);
return tot;
} int main()
{
a[].num=~0U>>;
while (scanf("%I64d",&n)!=EOF)
{
ans.Clear();
for (ll i=; i<=n; i++) scanf("%I64d",&a[i].num),a[i].pos=i;
sort(a+,a++n,cmp);
rankthem();
memset(f,,sizeof f);
for (ll i=; i<=n; i++)
{
ans.Add(sum(f[],g[i]-));
for (ll j=; j>; j--)
{
tep=sum(f[j-],g[i]-);
add(f[j],g[i],tep);
}
add(f[],g[i],);
}
ans.output();
}
return ;
}

POJ3378_Crazy Thairs的更多相关文章

  1. [poj3378] Crazy Thairs (DP + 树状数组维护 + 高精度)

    树状数组维护DP + 高精度 Description These days, Sempr is crazed on one problem named Crazy Thair. Given N (1 ...

  2. poj 3378 Crazy Thairs dp+线段树+大数

    题目链接 题目大意: 给出n个数, 让你求出有多少个5元组满足 i < j < k < l < m并且ai < aj < ak < al < am 我们 ...

  3. ●POJ 3378 Crazy Thairs

    题链: http://poj.org/problem?id=3378 题解: 树状数组维护,高精度. 依次考虑以每个位置结尾可以造成的贡献. 假设当前位置为i,为了达到5个元素的要求,我们需要求出,在 ...

  4. [POJ3378]Crazy Thairs

    Problem 给你一个数列,让你求由五个元素组成的顺序对的个数. Solution DP:用DP[i][j]表示把第j个作为五元组中第i个的方案数 则DP[i][j]=sum{DP[k][j-1]} ...

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

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

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

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

  7. [POJ 3378] Crazy Thairs

    Link: POJ 3378 传送门 Solution: 按序列长度$dp$, 设$dp[i][j]$为到第$i$个数,符合要求的序列长度为$j$时的序列个数, 易得转移方程:$dp[i][j]=\s ...

随机推荐

  1. 20155229 2016-2017-2 《Java程序设计》第二周学习总结

    20155229 2016-2017-2 <Java程序设计>第二周学习总结 教材学习内容总结 布尔:boolean类型可表示true和false %符号被用来作为控制符号前置,所以规定用 ...

  2. 实验一 Java开发环境的熟悉(Linux+Eclipse)

    实验一 Java开发环境的熟悉(Linux+Eclipse) 在Linux或Window或macOS中命令行下运行Java 在Linux 或Window或 macOS环境中 IDEA中调试设置断点 实 ...

  3. WPF Window背景半透明 ,蒙版操作实现

    原文:WPF Window背景半透明 ,蒙版操作实现 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/BYH371256/article/detail ...

  4. treegrid -表格树异步加载

    问题: 机构维护时,前端框架用的是easyui,如果同步全加载会出现页面延迟严重,影响用户体验 解决: 机构逐层加载,点击后加载 逐层加载会出现一个问题:子节点只有点击后才能加载子集 所以开始为叶子节 ...

  5. 【BZOJ4016】[FJOI2014]最短路径树问题

    [BZOJ4016][FJOI2014]最短路径树问题 题面 bzoj 洛谷 题解 虽然调了蛮久,但是思路还是蛮简单的2333 把最短路径树构出来,然后点分治就好啦 ps:如果树构萎了,这组数据可以卡 ...

  6. 两个字段联合约束(mysql)

    联合约束:ALTER TABLE `lywl_provider_package` ADD unique(providerId,packCode) 给一个表建唯一约束

  7. Ajax文件上传三式

    文件上传(三式) 1.urls.py文件 url(r'^upload.html$', views.upload), 2.views.py文件 import os def upload(request) ...

  8. 在django中使用django_debug_toolbar

    一.概述 django_debug_toolbar 是django的第三方工具包,给django扩展了调试功能. 包括查看执行的sql语句,db查询次数,request,headers,调试概览等. ...

  9. Teaching Machines to Understand Us 让机器理解我们 之一 引言

    Teaching Machines to Understand Us   By Tom Simonite  MIT Technology Review Vol.118 No.5 2015 让机器理解我 ...

  10. 【Python进阶】用 Python 统计字数

    问题描述: 用 Python 实现函数 count_words(),该函数输入字符串 s 和数字 n,返回 s 中 n 个出现频率最高的单词.返回值是一个元组列表,包含出现次数最高的 n 个单词及其次 ...