http://acm.hdu.edu.cn/showproblem.php?pid=4991

用f[i][j] 表示 前i个数以第i个数结尾的合法子序列的个数,则递推式不难写出:

f[i][j] = sum(f[k][j - 1]); 其中 k < i, 且a[k] < a[i]; 边界:f[i][1] = 1; 显然需要用数据结构来优化查询

如果不考虑离散的话,用一个数据结构,记录节点为a[i]的f值,同时维护一个区间f值之和,那么f[i][j] = query(0, a[i] - 1);然后考虑特定的顺序用f值更新数据结构中的信息

具体见代码(树状数组):

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <map>
#include <stack>
#include <string>
#define mem0(a) memset(a, 0, sizeof(a))
#define mem(a, b) memset(a, b, sizeof(a))
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
#define lr rt << 1
#define rr rt << 1 | 1
#define eps 0.0001
#define lowbit(x) ((x) & -(x))
#define memc(a, b) memcpy(a, b, sizeof(b))
typedef char Str[];
using namespace std;
#define LL long long
#define DL double map<int, int> Hash;
int mol = ;
int a[], f[][], b[], R[], c[], N, n, m; void init()
{
sort(a + , a + + n);
N = ;
for(int i = ; i <= n; i++) {
if(a[i] == a[i - ] && i > ) continue;
Hash[a[i]] = ++N;
}
}
int query(int p)
{
int ans = ;
while(p) {
ans += c[p];
if(ans >= mol) ans -= mol;
p -= lowbit(p);
}
return ans;
}
void update(int p, int x)
{
while(p <= N) {
c[p] += x;
if(c[p] >= mol) c[p] -= mol;
p += lowbit(p);
}
}
int main()
{
//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
while(~scanf("%d%d", &n, &m)) {
for(int i = ; i <= n; i++) {
scanf("%d", a + i);
}
memc(b, a);
init();
mem0(f);
//puts("d");
for(int i = ; i <= n; i++) f[i][] = ;
for(int i = ; i <= n; i++) R[i] = Hash[b[i]];
for(int j = ; j <= m; j++) {
mem0(c);
for(int i = ; i <= n; i++) {
f[i][j] = query(R[i] - );
update(R[i], f[i][j - ]);
//cout<< i<< " "<< j<< " "<< f[i][j]<< endl;
}
}
int ans = ;
for(int i = m; i <= n; i++) {
ans += f[i][m];
if(ans >= mol) ans -= mol;
}
cout<< ans<< endl;
}
return ;
}

另外用线段树写了一下, 不过超时(2000+ms)了,线段树才不到500ms,由此可见能用树状数组决不用线段树,递归线段树常数太大了

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <map>
#include <stack>
#include <string>
#define mem0(a) memset(a, 0, sizeof(a))
#define mem(a, b) memset(a, b, sizeof(a))
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
#define lr rt << 1
#define rr rt << 1 | 1
#define eps 0.0001
#define lowbit(x) ((x) & -(x))
#define memc(a, b) memcpy(a, b, sizeof(b))
typedef char Str[];
using namespace std;
#define LL long long
#define DL double
struct seg{
int sum;
}tree[ << ];
map<int, int> Hash;
int mol = ;
int a[], f[][], b[], R[], N, n, m; void init()
{
sort(a + , a + + n);
N = ;
for(int i = ; i <= n; i++) {
if(a[i] == a[i - ] && i > ) continue;
Hash[a[i]] = ++N;
}
}
void build(int l, int r, int rt)
{
tree[rt].sum = ;
if(l == r) return;
int m = (l + r) >> ;
build(lson);
build(rson);
}
void pushUP(int rt)
{
tree[rt].sum = tree[rt << ].sum + tree[rt<< | ].sum;
if(tree[rt].sum >= mol) tree[rt].sum -= mol;
}
void update(int p, int x, int l, int r, int rt)
{
if(l == r) {
tree[rt].sum += x;
if(tree[rt].sum >= mol) tree[rt].sum -= mol;
return;
}
int m = (l + r) >> ;
if(p <= m) update(p, x, lson);
else update(p, x, rson);
pushUP(rt);
}
int query(int L, int R, int l, int r, int rt)
{
if(L <= l && r <= R) {
return tree[rt].sum;
}
int m = (l + r) >> , res = ;
if(L <= m) res+= query(L, R, lson);
if(R > m) res += query(L, R, rson);
if(res >= mol) res -= mol;
return res;
}
int main()
{
//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
while(~scanf("%d%d", &n, &m)) {
for(int i = ; i <= n; i++) {
scanf("%d", a + i);
}
memc(b, a);
init();
mem0(f);
//puts("d");
for(int i = ; i <= n; i++) f[i][] = ;
for(int i = ; i <= n; i++) R[i] = Hash[b[i]];
for(int j = ; j <= m; j++) {
build(, N, );
for(int i = ; i <= n; i++) {
if(R[i] > ) f[i][j] = query(, R[i] - , , N, );
update(R[i], f[i][j - ], , N, );
}
}
int ans = ;
for(int i = m; i <= n; i++) {
ans += f[i][m];
if(ans >= mol) ans -= mol;
}
cout<< ans<< endl;
}
return ;
}

【HDU4991】树状数组的更多相关文章

  1. hdu4991 树状数组+dp

    这题说的是给了一个序列长度为n 然后求这个序列的严格递增序列长度是m的方案有多少种,如果用dp做那么对于状态有dp[n][m]=dp[10000][100],时间复杂度为n*m*n接受不了那么想想是否 ...

  2. HDU4991 Ordered Subsequence (树状数组优化DP)

    dp[i][j]表示以a[i]结尾的长度为j的上升子序列个数. 方程:dp[i][j]=sum(dp[k][j-1]),a[k]<a[i],1<=k<i. 求解目标:sum(dp[k ...

  3. BZOJ 1103: [POI2007]大都市meg [DFS序 树状数组]

    1103: [POI2007]大都市meg Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2221  Solved: 1179[Submit][Sta ...

  4. bzoj1878--离线+树状数组

    这题在线做很麻烦,所以我们选择离线. 首先预处理出数组next[i]表示i这个位置的颜色下一次出现的位置. 然后对与每种颜色第一次出现的位置x,将a[x]++. 将每个询问按左端点排序,再从左往右扫, ...

  5. codeforces 597C C. Subsequences(dp+树状数组)

    题目链接: C. Subsequences time limit per test 1 second memory limit per test 256 megabytes input standar ...

  6. BZOJ 2434: [Noi2011]阿狸的打字机 [AC自动机 Fail树 树状数组 DFS序]

    2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 2545  Solved: 1419[Submit][Sta ...

  7. BZOJ 3529: [Sdoi2014]数表 [莫比乌斯反演 树状数组]

    3529: [Sdoi2014]数表 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1399  Solved: 694[Submit][Status] ...

  8. BZOJ 3289: Mato的文件管理[莫队算法 树状数组]

    3289: Mato的文件管理 Time Limit: 40 Sec  Memory Limit: 128 MBSubmit: 2399  Solved: 988[Submit][Status][Di ...

  9. 【Codeforces163E】e-Government AC自动机fail树 + DFS序 + 树状数组

    E. e-Government time limit per test:1 second memory limit per test:256 megabytes input:standard inpu ...

随机推荐

  1. css 样式中 margin padding和top类定位的区别

    1 margin margin 是外边距的意思,是边框到外部另一元素之间的距离,允许使用负值 语法结构: margin:5px auto;                  意思上下为5,左右平均居中 ...

  2. 重磅!阿里发布《Java开发手册(泰山版)》

    最近,阿里的<Java开发手册>又更新了,这个版本历经一年的修炼,取名:<Java开发手册(泰山版)>正式出道. 正所谓无规矩不成方圆,在程序员的世界里,也存在很多规范,阿里出 ...

  3. 云开发静态网站托管现已支持 Angular 应用

    云开发静态托管是云开发提供的静态网站托管的能力,静态资源(HTML.CSS.JavaScript.字体等)的分发由腾讯云对象存储 COS 和拥有多个边缘网点的腾讯云 CDN 提供支持. 在云开发静态托 ...

  4. MVC-路由扩展-限制浏览器

    根据路由原理,MVC每次都会走获取路由上下文数据. 自定义Route 调用,以及完善其他代码 运行结果,当在谷浏览器执行时:

  5. python 基础篇 错误和异常处理

    语法错误 所谓语法错误,也就是你写的代码不符合编程规范,无法被识别与执行,比如下面这个例子: if name is not None print(name) If 语句漏掉了冒号,不符合 Python ...

  6. Golang Map实现(一)

    本文学习 Golang 的 Map 数据结构,以及map buckets 的数据组织结构. hash 表是什么 从大学的课本里面,我们学到:hash 表其实就是将key 通过hash算法映射到数组的某 ...

  7. 个人理解Linux文件权限--以前记录的,根据鸟哥的第二版去解释的

    ps:鸟哥的第三版私房菜印刷的有问题 上面的意思:d指的是目录 档案拥有者权限:r可读w可写,x,可运行, 同群组的权限:r可读,这段有个-号,表示不可写,x表示可运行 其他非本群组的权限:r可读,这 ...

  8. testlink配置修改

    1.      Read/write permissions报错 问题: Checking if  /var/testlink/logs/ directory exists [S] </B< ...

  9. node 搭载本地代理,处理web本地开发跨域问题

    var path = require('path') var httpProxy = require('http-proxy') var express = require('express') va ...

  10. Scrapy模拟登录信息

    携带cookie模拟登录 需要在爬虫里面自定义一个start_requests()的函数 里面的内容: def start_requests(self): cookies = '真实有效的cookie ...