【HDU4991】树状数组
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】树状数组的更多相关文章
- hdu4991 树状数组+dp
这题说的是给了一个序列长度为n 然后求这个序列的严格递增序列长度是m的方案有多少种,如果用dp做那么对于状态有dp[n][m]=dp[10000][100],时间复杂度为n*m*n接受不了那么想想是否 ...
- 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 ...
- BZOJ 1103: [POI2007]大都市meg [DFS序 树状数组]
1103: [POI2007]大都市meg Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2221 Solved: 1179[Submit][Sta ...
- bzoj1878--离线+树状数组
这题在线做很麻烦,所以我们选择离线. 首先预处理出数组next[i]表示i这个位置的颜色下一次出现的位置. 然后对与每种颜色第一次出现的位置x,将a[x]++. 将每个询问按左端点排序,再从左往右扫, ...
- codeforces 597C C. Subsequences(dp+树状数组)
题目链接: C. Subsequences time limit per test 1 second memory limit per test 256 megabytes input standar ...
- BZOJ 2434: [Noi2011]阿狸的打字机 [AC自动机 Fail树 树状数组 DFS序]
2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 2545 Solved: 1419[Submit][Sta ...
- BZOJ 3529: [Sdoi2014]数表 [莫比乌斯反演 树状数组]
3529: [Sdoi2014]数表 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1399 Solved: 694[Submit][Status] ...
- BZOJ 3289: Mato的文件管理[莫队算法 树状数组]
3289: Mato的文件管理 Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 2399 Solved: 988[Submit][Status][Di ...
- 【Codeforces163E】e-Government AC自动机fail树 + DFS序 + 树状数组
E. e-Government time limit per test:1 second memory limit per test:256 megabytes input:standard inpu ...
随机推荐
- Windows线程+进程通信
一 Windows线程进程 1)定义 按照MS的定义, Windows中的进程简单地说就是一个内存中的可执行程序, 提供程序运行的各种资源. 进程拥有虚拟的地址空间, 可执行代码, 数据, 对象句柄集 ...
- 代理模式是什么?如何在 C# 中实现代理模式
代理模式 并不是日常开发工作中常常用到的一种设计模式,也是一种不易被理解的一种设计模式.但是它会广泛的应用在系统框架.业务框架中. 定义 它的 定义 就如其它同大部分 设计模式 的定义类似,即不通俗也 ...
- Shellshock远程命令注入(CVE-2014-6271)漏洞复现
请勿用于非法用法,本帖仅为学习记录 shelshocke简介: shellshock即unix 系统下的bash shell的一个漏洞,Bash 4.3以及之前的版本在处理某些构造的环境变量时存在安全 ...
- C++创建动态库
[C++]创建动态库 有很多方法,这个只是其中一种 比较简洁的方法. char* __stdcall correction(char* str) char *_result = new char[se ...
- IDEA惊天bug:进程已结束,退出代码-1073741819 (0xC0000005)
由于昨天要写的文章没有写完,于是今天早上我四点半就"自然醒"了,心里面有事,睡觉也不安稳.洗漱完毕后,我打开电脑,正襟危坐,摆出一副要干架的态势,不能再拖了. 要写的文章中涉及到一 ...
- python 进阶篇 python 的值传递
值传递和引用传递 值传递,通常就是拷贝参数的值,然后传递给函数里的新变量,这样,原变量和新变量之间互相独立,互不影响. 引用传递,通常是指把参数的引用传给新的变量,这样,原变量和新变量就会指向同一块内 ...
- GC日志分析详解
点击返回上层目录 原创声明:作者:Arnold.zhao 博客园地址:https://www.cnblogs.com/zh94 GC日志分析详解 以ParallelGC为例,YoungGC日志解释如下 ...
- 一,连接Oracle 一
连接Oracle数据库方法: 一,使用sqlplus连接 二,使用第三方软件连接 sqlplus sqlplus 工具简介 (1).概述:sqlplus是在Linux下操作oracle的工具 (2). ...
- 7.哪些工具可以帮助查找bug或进行静态分析
哪些工具可以帮助查找bug或进行静态分析? PyChecker is a static analysis tool that detects the bugs in Python source cod ...
- Autofac的切面编程实现
*:first-child { margin-top: 0 !important; } .markdown-body>*:last-child { margin-bottom: 0 !impor ...