HDU 6348 序列计数 (树状数组 + DP)
序列计数
Time Limit: 4500/4000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 348 Accepted Submission(s): 117
由于结果可能很大,同时也是为了 ruin the legend, 你只需要输出结果对 1000000007(=109+7) 取模后的值。
接下来依次描述 T 组测试数据。对于每组测试数据:
第一行包含一个整数 n,表示排列的长度。
第二行包含 n 个整数 p1,p2, …, pn,表示排列的 n 个数。
保证 1≤T≤100,1≤n≤104,T 组测试数据的 n 之和 ≤105,p1,p2,…,pn 是 1,2,…,n 的一个排列。
除了样例,你可以认为给定的排列是从所有 1,2,…,n 的排列中等概率随机选出的。
4
1 2 3 4
4
1 3 2 4
Case #2: 4 5 2 0
Statistic | Submit | Discuss | Note
析:当时这个题目,我的第一感觉就是 LIS 加组合数,然后就是枚举长度为 i 的上升子序列有多少个,然后可以再枚举每个数,计算以第 j 个数为结束的上升子序列有多少个,这个是可以递推的,然后计算前面有多少个数比第 j 个数小,并且长度为 i - 1 的上升子序列有多少个,这个复杂度是O(n^3),怎么可能过呢,但是题目说了,这个排序是随机给的,虽然我不知道 LIS 最长是多少,但是肯定不会很大,因为我们平时做的题目时间要算最坏的是因为,后台基本是会有最坏的数据的,毕竟出题人要卡你时间么,这个题目说了是随机的,所以这个时间复杂度可能是在O(n^(5/2)) 左右吧(猜的),这样还是过不了的,但是还可以进行优化,在求长度为 i - 1 的上升子序列有多少个的时候,可以使用树状数组来进行优化,当然其他数据结构也是可以啦,现在复杂度应该就是O(n(3/2)*log(n)),最坏的话 1e4 * 1e2 * 14 左右,大约 1e7 ,时间上差不多。交上去一遍就过了。。。
代码如下:
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <cctype>
#include <cmath>
#include <stack>
#include <sstream>
#include <list>
#include <assert.h>
#include <bitset>
#include <numeric>
#define debug() puts("++++")
#define gcd(a, b) __gcd(a, b)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define fi first
#define se second
#define pb push_back
#define sqr(x) ((x)*(x))
#define ms(a,b) memset(a, b, sizeof a)
#define sz size()
#define be begin()
#define ed end()
#define pu push_up
#define pd push_down
#define cl clear()
#define lowbit(x) -x&x
//#define all 1,n,1
#define FOR(i,n,x) for(int i = (x); i < (n); ++i)
#define freopenr freopen("in.in", "r", stdin)
#define freopenw freopen("out.out", "w", stdout)
using namespace std; typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f;
const LL LNF = 1e17;
const double inf = 1e20;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int maxn = 1e4 + 20;
const int maxm = 1e6 + 10;
const int mod = 1000000007;
const int dr[] = {-1, 1, 0, 0, 1, 1, -1, -1};
const int dc[] = {0, 0, 1, -1, 1, -1, 1, -1};
const char *de[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
int n, m;
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
inline bool is_in(int r, int c) {
return r >= 0 && r < n && c >= 0 && c < m;
}
inline int readInt(){ int x; scanf("%d", &x); return x; } int sum[2][maxn]; void add(int i, int x, LL c){
while(x <= n){
sum[i][x] += c;
if(sum[i][x] >= mod) sum[i][x] -= mod;
x += lowbit(x);
}
} int query(int i, int x){
int ans = 0;
while(x){
ans += sum[i][x];
if(ans >= mod) ans -= mod;
x -= lowbit(x);
}
return ans;
} int dp[maxn], a[maxn]; int main(){
int T; cin >> T;
for(int kase = 1; kase <= T; ++kase){
scanf("%d", &n);
for(int i = 1; i <= n; ++i){
scanf("%d", a + i);
dp[i] = 1;
}
printf("Case #%d:", kase);
int cur = 0;
printf(" %d", n);
cur = 1;
for(int i = 2; i <= n; ++i, cur ^= 1){
ms(sum[cur^1], 0);
int ans = 0;
for(int j = 1; j <= n; ++j){
int tmp = query(cur^1, a[j]);
add(cur^1, a[j], dp[j]);
dp[j] = tmp;
ans += tmp;
if(ans >= mod) ans -= mod;
}
if(ans == 0){
for(int j = i; j <= n; ++j) printf(" 0");
break;
}
printf(" %d", ans);
}
printf("\n");
}
return 0;
}
HDU 6348 序列计数 (树状数组 + DP)的更多相关文章
- Apple Tree POJ - 3321 dfs序列构造树状数组(好题)
There is an apple tree outside of kaka's house. Every autumn, a lot of apples will grow in the tree. ...
- 【树状数组+dp】HDU 5542 The Battle of Chibi
http://acm.hdu.edu.cn/showproblem.php?pid=5542 [题意] 给定长为n的序列,问有多少个长为m的严格上升子序列? [思路] dp[i][j]表示以a[i]结 ...
- hdu 4622 Reincarnation trie树+树状数组/dp
题意:给你一个字符串和m个询问,问你l,r这个区间内出现过多少字串. 连接:http://acm.hdu.edu.cn/showproblem.php?pid=4622 网上也有用后缀数组搞得. 思路 ...
- HDU 6078 Wavel Sequence 树状数组优化DP
Wavel Sequence Problem Description Have you ever seen the wave? It's a wonderful view of nature. Lit ...
- hdu 3030 Increasing Speed Limits (离散化+树状数组+DP思想)
Increasing Speed Limits Time Limit: 2000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java ...
- hdu 2227(树状数组+dp)
Find the nondecreasing subsequences Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/3 ...
- HDU 6447 YJJ’s Salesman (树状数组 + DP + 离散)
题意: 二维平面上N个点,从(0,0)出发到(1e9,1e9),每次只能往右,上,右上三个方向移动, 该N个点只有从它的左下方格点可达,此时可获得收益.求该过程最大收益. 分析:我们很容易就可以想到用 ...
- hdu 4991(树状数组+DP)
Ordered Subsequence Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- Codeforces 597C. Subsequences (树状数组+dp)
题目链接:http://codeforces.com/contest/597/problem/C 给你n和数(1~n各不同),问你长为k+1的上升自序列有多少. dp[i][j] 表示末尾数字为i 长 ...
随机推荐
- selenium使用技巧
标签(空格分隔): selenium 我们进行selenium的时候,就是通过webdriver,对浏览器做一些操作的: webdriver,除了find操作,之外还有哪些方法和属性呢? 1.获取当前 ...
- pycharm连接mysql数据库插入中文数据时出现1366编码错误
创建数据库的时候应该这样创建: create database xxxxxxx DEFAULT CHARSET utf8 COLLATE utf8_general_ci:
- Servlet第五篇(会话技术之Session)
Session 什么是Session Session 是另一种记录浏览器状态的机制.不同的是Cookie保存在浏览器中,Session保存在服务器中.用户使用浏览器访问服务器的时候,服务器把用户的信息 ...
- 小强学渲染之Unity Shader噪声应用
之前玩Tencent的仙剑4手游时,杀死boss会看到boss有“消融”的效果,就是身体上有多个洞洞然后往四周扩散直至尸体完全消失,但效果是没有关闭背面剔除的“穿帮”效果,可能也是考虑性能因素. em ...
- mysql学习笔记--数据库视图
一.视图 1. 概念 a. 视图是一张虚拟表,它表示一张表的部分或多张表的综合的结构 b. 视图仅仅是表结构,没有数据.视图的结构和数据建立在表的基础上 2. 创建视图 a. 语法: create [ ...
- Python __dict__属性详解
本文转载自 https://www.cnblogs.com/alvin2010/p/9102344.html 感谢 //偏执 大佬 我们都知道Python一切皆对象,那么Python究竟是怎么管理对象 ...
- Oracle数值处理函数
1.绝对值:abs() select abs(-2) value from dual; 2.取整函数(大):ceil() select ceil(-2.001) value from du ...
- 更换Appsecrect应该要注意的问题
1. 有时候因为需要,有些地方需要填写Appsecrect, 但是大家都知道微信公众平台上这个值 即使你自己是管理员是看不到的,只能重置,但是重置后,一定要记住刷新AccessToken啊,不然就尴尬 ...
- Docker代理设置方法
1.注意Docker版本(此处版本为docker-ce-18.06.1) docker version 2.编辑Docker服务配置文件 vim /usr/lib/systemd/system/doc ...
- angular中文文档的滚动条样式
个人感觉angular中文文档的滚动条样式非常棒,于是乎就扒了下来 https://www.angular.cn/ body::-webkit-scrollbar { /* 定义了滚动条整体的样式 * ...