序列计数

Time Limit: 4500/4000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 348    Accepted Submission(s): 117

Problem Description
度度熊了解到,1,2,…,n 的排列一共有 n!=n×(n−1)×⋯×1 个。现在度度熊从所有排列中等概率随机选出一个排列 p1,p2,…,pn,你需要对 k=1,2,3,…,n 分别求出长度为 k 的上升子序列个数,也就是计算满足 1≤a1 < a2 < … < ak ≤n 且 pa1 <pa2< … < pak 的 k 元组 (a1,a2,…,ak) 的个数。

由于结果可能很大,同时也是为了 ruin the legend, 你只需要输出结果对 1000000007(=109+7) 取模后的值。

 
Input
第一行包含一个整数 T,表示有 T 组测试数据。

接下来依次描述 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 的排列中等概率随机选出的。

 
Output
对于每组测试数据,输出一行信息 "Case #x: c1 c2 ... cn"(不含引号),其中 x 表示这是第 x 组测试数据,ci 表示长度为 i 的上升子序列个数对 1000000007(=109+7) 取模后的值,相邻的两个数中间用一个空格隔开,行末不要有多余空格。
 
Sample Input
2
4
1 2 3 4
4
1 3 2 4
 
Sample Output
Case #1: 4 6 4 1
Case #2: 4 5 2 0
 
Source
 
Recommend
chendu
 

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)的更多相关文章

  1. 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. ...

  2. 【树状数组+dp】HDU 5542 The Battle of Chibi

    http://acm.hdu.edu.cn/showproblem.php?pid=5542 [题意] 给定长为n的序列,问有多少个长为m的严格上升子序列? [思路] dp[i][j]表示以a[i]结 ...

  3. hdu 4622 Reincarnation trie树+树状数组/dp

    题意:给你一个字符串和m个询问,问你l,r这个区间内出现过多少字串. 连接:http://acm.hdu.edu.cn/showproblem.php?pid=4622 网上也有用后缀数组搞得. 思路 ...

  4. HDU 6078 Wavel Sequence 树状数组优化DP

    Wavel Sequence Problem Description Have you ever seen the wave? It's a wonderful view of nature. Lit ...

  5. hdu 3030 Increasing Speed Limits (离散化+树状数组+DP思想)

    Increasing Speed Limits Time Limit: 2000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java ...

  6. hdu 2227(树状数组+dp)

    Find the nondecreasing subsequences Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/3 ...

  7. HDU 6447 YJJ’s Salesman (树状数组 + DP + 离散)

    题意: 二维平面上N个点,从(0,0)出发到(1e9,1e9),每次只能往右,上,右上三个方向移动, 该N个点只有从它的左下方格点可达,此时可获得收益.求该过程最大收益. 分析:我们很容易就可以想到用 ...

  8. hdu 4991(树状数组+DP)

    Ordered Subsequence Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  9. Codeforces 597C. Subsequences (树状数组+dp)

    题目链接:http://codeforces.com/contest/597/problem/C 给你n和数(1~n各不同),问你长为k+1的上升自序列有多少. dp[i][j] 表示末尾数字为i 长 ...

随机推荐

  1. Redis安全以及备份还原

    启用密码 配置密码,配置文件中添加节点requirepass,如下root即passwordrequirepass root可以在登陆的时候用-a 指定password登陆,也可以不指定,登陆之后使用 ...

  2. Neural Network Virtual Machine

    深度学习Stack 为什么提出NNVM? 深度学习框架现状 - “碎片化” 目前,深度学习应用框架呈现出高度的“碎片化(fragmentation)”倾向,这主要是由于下述两个原因: 1. 深度学习正 ...

  3. python基础之语句字符串

    python的种类: jpython                 java写的python ironpython            c#写的python cpython             ...

  4. Ionic2+WebApi 导出Excel转Pdf文件。

    步骤: 1.首先在WebApi中先把excel生成好. 2.把excel转成Pdf,并返回下载的链接. 3.Ionic2的页面做好下载的接口. 嗯~思路很清晰,那么下面就来详细的操作吧. 以下是H5的 ...

  5. 双硬盘,win10安装到固态盘

    1.PE下格式化固态盘的系统盘 2.打开DG分区工具,查看固态盘的系统盘是否为激活状态,红色为激活,如果不是,激活一下 3.用windows安装器,或者hdd安装win10到固态盘 4.bios中启动 ...

  6. php使用redis的几种常见方式和用法

    一.简单的字符串缓存 比如针对一些sql查询较慢,更新不频繁的数据进行缓存. <?php $redis = new Redis(); $redis->connect('127.0.0.1' ...

  7. Div+CSS+JQuery实现选项卡,即通过点击不同的li跳转到不同的div中显示不同的内容或者执行不同的操作。

    1.代码 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html>   ...

  8. 使用Json.net对Json进行遍历

    公司使用了一种伪Json, 当value为字符串并且以"@"开头时, 要替换成真实的值, 比如{"name":"@countryName"} ...

  9. c++常用小算法

    这篇文章列出了一些简单常用的C++容器算法,C++标准库中事实上提供了很多的算法并且有详细的介绍.如果需要详细的了解这些算法可以 参考C++在线参考手册 algrithm . 1 排序 在 #incl ...

  10. js 内置对象参考 (Array,String, Math, Data, Number)

    var str = "helloWorld"; var strOne = "helloWorld"; // charAt() 返回在指定位置的字符. var a ...