序列计数

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. unfortunately,*********** has stopped及卸载模拟器上的多余不用apk

    虽然不知道是怎么了,但是项目进不去了,害的我一脸雾水,百度了下好像没什么人遇到过这问题,都没找到解决办法,那只好来个简单粗暴的,卸载重新安装apk ,希望有大神知道原因和其他方法的欢迎留言或者评价给出 ...

  2. 云笔记项目-Spring事务学习-传播SUPPORTS

    接下来测试事务传播属性SUPPORTS Service层 Service层将方法的事务传播属性设置为SUPPORTS LayerT层代码 package LayerT; import javax.an ...

  3. php 安装最新的redis连接扩展

    用于与redis连接的Php扩展[RC表示公测,我们用的是不带RC的稳定版本]下载包地址:http://pecl.php.net/package/redis 最新稳定版本:4.3.0 下载包:# wg ...

  4. 《Orange‘s》 Bochs环境配置

    安装配置bochs之前先写一个简单的引导扇区用来测试: org 07c00h mov ax,cs mov ds,ax mov es,ax call DispStr jmp $ DispStr: mov ...

  5. Python学习笔记4基本数据类型续

    start  16:36 时间格式化 程序计时:指测量起止动作所经历的时间的过程 实例四文本进度条 #a表示星号被复制的的次数 文本进度条的动态刷新 实现刷新功能的简单代码,但你会发现并没有实现在同一 ...

  6. UML图之类图(转)

    基本概念 类图(Class Diagram): 类图是面向对象系统建模中最常用和最重要的图,是定义其它图的基础.类图主要是用来显示系统中的类.接口以及它们之间的静态结构和关系的一种静态模型. 类图的3 ...

  7. Spring整合quartz关闭,关闭Tomcat Servlet容器时内存泄漏

    出错信息 22-Sep-2017 06:19:51.064 WARNING [main] org.apache.catalina.loader.WebappClassLoaderBase.clearR ...

  8. node 常用模块及方法fs,url,http,path

    http://www.cnblogs.com/mangoxin/p/5664615.html https://www.liaoxuefeng.com/wiki/001434446689867b2715 ...

  9. jango路由层

    简单的路由配置: urls.py from django.contrib import admin from django.urls import path, re_path from book_ap ...

  10. FastDFS防盗链

    FastDFS扩展模块内置了通过token来实现防盗链的功能.开启防盗链后,访问文件是需要在url中加两个参数:token和ts.ts为时间戳,token为系统根据时间戳和密码生成的信物.为了系统的安 ...