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. Gradle系列之Groovy基础篇

    原文发于微信公众号 jzman-blog,欢迎关注交流. 上一篇学习了 Gradle 的入门知识,Gradle 基于 Groovy,今天学习一下 Groovy 的基础知识,Groovy 是基于 JVM ...

  2. vue2.x学习笔记(五)

    接着前面的内容:https://www.cnblogs.com/yanggb/p/12571062.html. 计算属性 模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的.如果在模板中放入太 ...

  3. pytorch 孪生神经网络DNN

    代码内容请见: https://github.com/LiuXinyu12378/DNN-network

  4. 8个超好用的Python内置函数,提升效率必备(小白必看)

    python中有许多内置函数,不像print那么广为人知,但它们却异常的强大,用好了可以大大提高代码效率. 这次来梳理下8个好用的python内置函数. 1.set() 当需要对一个列表进行去重操作的 ...

  5. 只会Vue怎么开发小程序?vue和微信小程序的到底有哪些区别?

    写了vue项目和小程序,发现二者有许多相同之处,在此想总结一下二者的共同点和区别. 一.生命周期 先贴两张生命周期图对比下: vue生命周期 小程序生命周期 相比之下,小程序的钩子函数要简单得多. v ...

  6. 关于Swiper和vue数据顺序加载问题处理

    在使用swiper插件的时候,常常因为异步加载数据产生的顺序问题而使插件不能正常实行,所以可以使用vue的updated来解决. 问:什么时候 进updated方法? 答:只有事先设置好的data变量 ...

  7. ajax轮询思路

    以我个人理解 ,ajax短轮询就是用定时器,定时请求数据库,然后把有用的数据做处理 ajax长轮询恩 就是在 ajax回调函数,继续调用ajax请求

  8. 不论是 Basic Auth 还是 Digest Auth,都会有 Authorization 字段

    GET /dir/index.html HTTP/1.0 Host: localhost Authorization: Digest username="Mufasa", real ...

  9. Data Flow Diagram with Examples - Customer Service System

    Data Flow Diagram with Examples - Customer Service System Data Flow Diagram (DFD) provides a visual ...

  10. 一篇文章带你编写10种语言HelloWorld

    0,编程语言排行榜 计算机编程语言众多,世界上大概有600 多种编程语言,但是流行的也就几十种.我们来看下编程语言排行榜,下面介绍两种语言排行榜. Ⅰ TIOBE 指数 该指数每月更新一次,它监控了近 ...