题意:给定n个数,求包含最大值和最小值的子集(数字连续)和子序列(数字不连续)的个数。

分析:

1、如果n个数都相同,则子集个数为N * (N + 1) / 2,子序列个数为2N-1。

2、将序列从头到尾扫一遍,每当找到一个最大值和最小值的位置maxid,minid,就以这两个位置的区间为基准,计算集合数。

例如:3 1 4 3 1

当i=2时,此时maxid=2,minid=1,因此由最大值和最小值---1和4能形成两个子集:3 1 4 和 1 4,即min(minid + 1, maxid + 1)个

当i=3时,此时maxid=2,minid=1,因此由最大值和最小值---1和4继续扩展,又能形成两个子集:3 1 4 3 和 1 4 3,

当i=4时,此时maxid=2,minid=4,因此由新的最大值和最小值---1和4继续扩展,又能形成三个子集:3 1 4 3 1 ,1 4 3 1,4 3 1。

3、记录序列中最大值和最小值的个数,分别为maxnum,minnum。

子序列个数为,只由最小值形成的集合数a*只由最大值形成的集合数b*不是最小值和最大值的数形成的集合数c

因为子序列中必须有最大值和最小值,因此a和b不能为空集,所以a=2minnum-1,b=2maxnum-1。

而c可以为空集,所以c=2n-minnum-maxnum

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<cmath>
#include<iostream>
#include<sstream>
#include<iterator>
#include<algorithm>
#include<string>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<deque>
#include<queue>
#include<list>
#define lowbit(x) (x & (-x))
const double eps = 1e-9;
inline int dcmp(double a, double b){
if(fabs(a - b) < eps) return 0;
return a > b ? 1 : -1;
}
typedef long long LL;
typedef unsigned long long ULL;
const int INT_INF = 0x3f3f3f3f;
const int INT_M_INF = 0x7f7f7f7f;
const LL LL_INF = 0x3f3f3f3f3f3f3f3f;
const LL LL_M_INF = 0x7f7f7f7f7f7f7f7f;
const int dr[] = {0, 0, -1, 1, -1, -1, 1, 1};
const int dc[] = {-1, 1, 0, 0, -1, 1, -1, 1};
const LL MOD = 1000000007;
const double pi = acos(-1.0);
const int MAXN = 100000 + 10;
const int MAXT = 1000 + 10;
using namespace std;
LL a[MAXN];
LL POW[MAXN];
void init(){
POW[0] = 1;
for(int i = 1; i < MAXN; ++i){
POW[i] = (POW[i - 1] * 2) % MOD;
}
}
int main(){
init();
int T;
scanf("%d", &T);
while(T--){
int N;
scanf("%d", &N);
LL _min = LL_INF;
LL _max = 0;
for(int i = 0; i < N; ++i){
scanf("%lld", &a[i]);
_max = max(_max, a[i]);
_min = min(_min, a[i]);
}
if(_max == _min){
LL sum1 = N * (N + 1) / 2;
LL sum2 = POW[N] - 1;
printf("%lld %lld\n", sum1, sum2);
continue;
}
int maxnum = 0;
int minnum = 0;
int minid = -1, maxid = -1;
LL sum1 = 0;
for(int i = 0; i < N; ++i){
if(a[i] == _min){
minid = i;
++minnum;
}
if(a[i] == _max){
maxid = i;
++maxnum;
}
(sum1 += min(minid + 1, maxid + 1)) %= MOD;
}
LL sum2 = ((((POW[minnum] - 1) * (POW[maxnum] - 1)) % MOD) * (POW[N - minnum - maxnum])) % MOD;
printf("%lld %lld\n", sum1, sum2);
}
return 0;
}

  

SPOJ - AMR11H Array Diversity (排列组合)的更多相关文章

  1. SPOJ - AMR11H Array Diversity (水题排列组合或容斥)

    题意:给定一个序列,让你求两种数,一个是求一个子序列,包含最大值和最小值,再就是求一个子集包含最大值和最小值. 析:求子序列,从前往记录一下最大值和最小值的位置,然后从前往后扫一遍,每个位置求一下数目 ...

  2. codeforces 57 C Array(简单排列组合)

    C. Array time limit per test 2 seconds memory limit per test 256 megabytes input standard input outp ...

  3. Spring-2-H Array Diversity(SPOJ AMR11H)解题报告及测试数据

    Array Diversity Time Limit:404MS     Memory Limit:0KB     64bit IO Format:%lld & %llu   Descript ...

  4. 排列组合或容斥原理 SPOJ - AMR11H

    题目链接: https://vjudge.net/contest/237052#problem/H 这里给你一串数字,让你计算同时拥有这串数字最大值和最小值的子集(连续)和子序列(可以不连续)的数量, ...

  5. [leetcode] 题型整理之排列组合

    一般用dfs来做 最简单的一种: 17. Letter Combinations of a Phone Number Given a digit string, return all possible ...

  6. 排列组合算法(PHP)

    用php实现的排列组合算法.使用递归算法,效率低,胜在简单易懂.可对付元素不多的情况. //从$input数组中取$m个数的组合算法 function comb($input, $m) { if($m ...

  7. js 排列 组合 的一个简单例子

    最近工作项目需要用到js排列组合,于是就写了一个简单的demo. 前几天在网上找到一个写全排列A(n,n)的code感觉还可以,于是贴出来了, 排列的实现方式: 全排列主要用到的是递归和数组的插入 比 ...

  8. PHP的排列组合问题 分别从每一个集合中取出一个元素进行组合,问有多少种组合?

    首先说明这是一个数学的排列组合问题C(m,n) = m!/(n!*(m-n)!) 比如:有集合('粉色','红色','蓝色','黑色'),('38码','39码','40码'),('大号','中号') ...

  9. Day4:T3搜索 T4数学题排列组合

    T3:搜索 很出名的题吧,费解的开关 同T2一样也是一题很考思考的 附上题解再解释吧: 对于每个状态,算法只需要枚举第一行改变哪些灯的状态,只要第一行的状态固定了,接下来的状态改变方法都是唯一的:每一 ...

随机推荐

  1. Flask与Django哪个更好更实用呢?砖家是这么认为的

        这一周我打算做一个 Flask 教程.本文先把 Flask 和 Django 做一个比对,因为我对这两个 Python Web 框架都有实际的开发经验.希望我可以帮助您选择学习哪个框架,因为学 ...

  2. [Verilog] indexed part-select +:

      That syntax is called an indexed part-select. The first term is the bit offset and the second term ...

  3. 078、Java数组之数组的引用传递

    01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...

  4. redis.rpm 安装

    yum install jemalloc wget http://www6.atomicorp.com/channels/atomic/centos/6/x86_64/RPMS/redis-3.0.7 ...

  5. 二 配置数据字典&异步查询客户

    数据字典: 字典表和客户表的关系 配置字典表 配置客户表 Spring管理映射文件 1 字典表和客户表的关系 2 配置字典表 3  配置客户表 4  Spring管理映射文件 异步查询客户: 页面加载 ...

  6. SciPy 线性代数

    章节 SciPy 介绍 SciPy 安装 SciPy 基础功能 SciPy 特殊函数 SciPy k均值聚类 SciPy 常量 SciPy fftpack(傅里叶变换) SciPy 积分 SciPy ...

  7. python2学习------基础语法5(常用容器以及相关操作)

    1.list(列表) #生成数据list a=[x for x in range(10)]; #print a; #遍历list for i in a: pass; #print i; #追加元素 a ...

  8. C语言整理复习——指针

    指针是C的精华,不会指针就等于没学C.但指针又是C里最难理解的部分,所以特意写下这篇博客整理思路. 一.指针类型的声明 C的数据类型由整型.浮点型.字符型.布尔型.指针这几部分构成.前四种类型比较好理 ...

  9. Codestorm:Counting Triangles 查各种三角形的个数

    题目链接:https://www.hackerrank.com/contests/codestorm/challenges/ilia 这周六玩了一天的Codestorm,这个题目是真的很好玩,无奈只做 ...

  10. python merge、join、concat用法与区别

     由于合并变化较大,以后函数可能会修改,只给出一些例子作为参考 总结: merge.join 1.当没有索引时:merge.join为按照一定条件合并 2.当有索引.并按照索引合并时,得到结果为两者混 ...