序列计数

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. 吴裕雄 python 数据可视化

    import pandas as pd df = pd.read_csv("F:\\python3_pachongAndDatareduce\\data\\pandas data\\taob ...

  2. JQUERY之表单验证案例

    <!-- 需求: 用户注册页面要有用户名.密码.确认密码.邮箱 用户名文本框:用户名不能为空,且必须为数字与字母的6到12位的组合 密码框:密码不能为空,六到八位数字或字母的组合 确认密码框:确 ...

  3. 第二次oo博客作业--多线程电梯

    这次的系列作业是写一个电梯调度,主要目的是让我们熟悉多线程. 第一次作业是一个傻瓜电梯的调度问题,要求也很简单,即每次接一个人就行了.我只用了两个线程,一个是输入线程,一个是电梯线程,输入线程负责从标 ...

  4. Game Engine Architecture 10

    [Game Engine Architecture 10] 1.Full-Screen Antialiasing (FSAA) also known as super-sampled antialia ...

  5. pip安装scrapy出错解决措施

    安装报错提示: building 'twisted.test.raiser' extensionerror: Microsoft Visual C++ 14.0 is required. Get it ...

  6. java List递归排序,传统方式和java8 Stream优化递归,无序的列表按照父级关系进行排序(两种排序类型)

    当有一个List列表是无序的,List中的数据有parentid进行关联,通过java排序成两种排序类型: 所用的测试列表最顶级无parentid,若为特殊值,修改下判断方法即可. 第一种排序:按照树 ...

  7. 窗体背景和png

    窗体背景不要使用png格式图片,当窗体组件透明时,png会带来无穷的麻烦. 能不用png就不要用,截取图像也不要用Format32bppPArgb,特殊情况除外 Bitmap bkbmp = (Ima ...

  8. 第四周博客作业 <西北师范大学| 周安伟>

    一,助教博客链接https://home.cnblogs.com/u/zaw-315/ 二,本周点评作业量点评23份,对提交的优秀作业代码进行运行一份博客问题无法点评问题博客链接:https://ww ...

  9. POJ-3159.Candies.(差分约束 + Spfa)

    Candies Time Limit: 1500MS   Memory Limit: 131072K Total Submissions: 40407   Accepted: 11367 Descri ...

  10. 解析ReentrantLock实现原理

    在Java中通常实现锁有两种方式,一种是synchronized关键字,另一种是Lock(Lock的实现主要有ReentrantLock.ReadLock和WriteLock).synchronize ...