SPOJ - AMR11H (容斥原理)
Enough with this Harry Potter, please! What are we, twelve-year olds? Let's get our teeth into some real pumpkin pasties -- oops, programming problems!
Here we go!
Let's define the diversity of a list of numbers to be the difference between the largest and smallest number in the list.
For example, the diversity of the list (1, -1, 2, 7) = 7 - (-1) = 8.
A substring of a list is considered a non-empty sequence of contiguous numbers from the list. For example, for the list (1,3,7), the substrings are (1), (3), (7), (1,3), (3,7), (1,3,7). A subsequence of a list is defined to be a non-empty sequence of numbers obtained by deleting some elements from the list. For example, for the list (1,3,7), the subsequences are (1), (3), (7), (1,3), (3,7), (1,7), (1,3,7).
Given a list of length N find the number of substrings and subsequences in this list with the maximum diversity. If a substring/subsequence having maximum diversity occurs multiple times in the list, each of its occurences adds towards the answer. And tell Harry Potter your answer
Input (STDIN):
The first line contains T, the number of test cases. Then follow T test case blocks.
Each blocks starts with the first line containing the number N.
The second line contains a list of numbers in this list.
Output (STDOUT):
For each test case, output the number of substrings and the number of subsequences in this list with the maximum diversity.
Since the answers maybe very large, output them modulo 1000000007.
Constraints:
T <= 10
N <= 100,000
Each number in the list is between 1 and 100,000 inclusive.
Sample Input:
3
3
1 2 3
4
1 4 3 4
3
3 2 1
Sample Output:
1 2
3 6
1 2
题意:给你一串数字,给出一个差异性的定义(这串数字中最大值和最小值的差),问你这串数字的连续字串和非连续字串中差异性和原串相同的各有几个。
思路:连续的字串我们可以这样求
例:3 5 1 4 3 5 2 3
定义a,b分别是当前最小值和最大值的位置
a=0,b=0
for循环从i=1遍历到i=8(n=8),s[是存原串的数组
for(i=1;i<=n;i++){
if(s[i]==mx)//mx是最大值
{
b=i;
}
if(s[i]==mn)//mn是最小值
{
a=i;
}
sum=(sum+min(a,b))%mod;
}
为什么可以这样呢
当i=1时,对于i<=1的所有字串,没有任何字串的差异性可以和原串相等(因为它没有原串的最大值和最小值),所以sum=sum+0;
当i=2时,对于i<=2的所有字串,没有任何字串的差异性可以和原串相等(因为它只有原串的最大值),所以sum=sum+0;此时b=2;
当i=3时,对于i<=3的所有字串,原串的最大值和最小值都可以在i<=3中找到,我们以2<=i<=3为基本串,在它前面再加上连续的数字
可以找到2种情况(5,1[基础串])(3,5,1),此时a=3,b=2;所以sum=sum+min(a,b)=2;
当i=4时,,原串的最大值和最小值都可以在i<=4中找到,而我们可以再i=3的基础上在后面加上连续的数字,又可以找到两种新的情况(5,1,4)
(3,5,1,4);此时a=3,b=2;sum=sum+min(a,b)=4;
当i=5时,,原串的最大值和最小值都可以在i<=5中找到,而我们可以再i=4的基础上在后面加上s[5],又可以找到两种新的情况(5,1,4,3)
(3,5,1,4,3);此时a=3,b=2;sum=sum+min(a,b)=6
当i=6时,,因为s[6]是最原串的最大值,所以我们可以把基础串往后移一些(往后移了以后得到的子串数可以更多(1,4,3,5[基础串])(5,1,4,3,5),(3,5,1,3,4,5)),此时a=3,b=5,我们可以发现每次加的个数等于a,b中最小的那个,因为假设我们的基础串前面有3个数字,
我们可以选择加倒数第一个;选倒数第一个和倒数第二个;选倒数第一,倒数第二,倒数第三个。一共三种情况(因为要连续的),所以基础串前面的数字的个数越多越好。
而算不连续串时,我们可以用到容斥定理来算s【既有最大又有最小的串数】=s【总数】-s【没有最大】-s【没有最小】+s【既没最大又没最小】;
代码:
·
#include<stdio.h>
#define INF 0x7fffffff
#define ll long long
#define mod 1000000007
ll s[100050];
ll bin[100050];
ll min(int a,int b){
if(a>b)
return b;
return a;
}
void init(){
ll i;
ll r=1;
bin[0]=1;
for(i=1;i<=100005;i++){
r=(r*2)%mod;
bin[i]=r;
}
}
int main(){
int t;
init();
int n,i,j;
ll mx1,mn1,mx,mn;
scanf("%d",&t);
while(t--){
mx=mn=1;
mx1=0;
mn1=INF;
scanf("%d",&n);
for(i=1;i<=n;i++){
scanf("%lld",&s[i]);
if(s[i]<mn1){
mn=1;
mn1=s[i];
}
else if(s[i]==mn1)
mn++; //计算最小值的个数
if(s[i]>mx1){
mx=1;
mx1=s[i];
}
else if(s[i]==mx1)
mx++;
}
ll a=0,b=0;
ll sum=0;
for(i=1;i<=n;i++){
if(s[i]==mn1)
a=i;
if(s[i]==mx1)
b=i;
//printf("%d %d\n",a,b);
sum=(min(a,b)+sum)%mod;
}
ll ans=0;
if(mn1!=mx1){//判断特殊情况,如果最大值和最小值相等时,就说明整个数列都是同一个数,那么满足条件的非连续子序列的个数就是2的n次方-1
ans=(bin[n]-bin[n-mn]-bin[n-mx]+bin[n-mx-mn]+mod)%mod;
if(ans<0)//因为可能出现一种极端情况(bin[n-mx]和bin[n-mn]的值都接近与mod,bin[n]和bin[n-mx-mn]的值接近于0,ans的值就可能是负数)
ans+=mod;//在这里wa了七八发,知道真相的我感觉要吐血了
}
else
ans=(bin[n]-1+mod)%mod;
printf("%lld %lld\n",sum,ans);
}
return 0;
}
SPOJ - AMR11H (容斥原理)的更多相关文章
- 排列组合或容斥原理 SPOJ - AMR11H
题目链接: https://vjudge.net/contest/237052#problem/H 这里给你一串数字,让你计算同时拥有这串数字最大值和最小值的子集(连续)和子序列(可以不连续)的数量, ...
- SPOJ - AMR11H
Array Diversity Time Limit: 404MS Memory Limit: 1572864KB 64bit IO Format: %lld & %llu Submi ...
- Spring-2-H Array Diversity(SPOJ AMR11H)解题报告及测试数据
Array Diversity Time Limit:404MS Memory Limit:0KB 64bit IO Format:%lld & %llu Descript ...
- SPOJ - AMR11H Array Diversity (水题排列组合或容斥)
题意:给定一个序列,让你求两种数,一个是求一个子序列,包含最大值和最小值,再就是求一个子集包含最大值和最小值. 析:求子序列,从前往记录一下最大值和最小值的位置,然后从前往后扫一遍,每个位置求一下数目 ...
- SPOJ - AMR11H Array Diversity (排列组合)
题意:给定n个数,求包含最大值和最小值的子集(数字连续)和子序列(数字不连续)的个数. 分析: 1.如果n个数都相同,则子集个数为N * (N + 1) / 2,子序列个数为2N-1. 2.将序列从头 ...
- 2018.11.18 spoj Triple Sums(容斥原理+fft)
传送门 这次fftfftfft乱搞居然没有被卡常? 题目简述:给你nnn个数,每三个数ai,aj,ak(i<j<k)a_i,a_j,a_k(i<j<k)ai,aj,ak( ...
- SPOJ Triple Sums(FFT+容斥原理)
# include <cstdio> # include <cstring> # include <cstdlib> # include <iostream& ...
- SPOJ TSUM Triple Sums(FFT + 容斥)
题目 Source http://www.spoj.com/problems/TSUM/ Description You're given a sequence s of N distinct int ...
- SPOJ PGCD (mobius反演 + 分块)
转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlove 题意 :求满足gcd(i , j)是素数(1 &l ...
随机推荐
- android------基础面试题
1. Android的四大组件是哪些,它们的作用? 答:Activity:Activity是Android程序与用户交互的窗口,是Android构造块中最基本的一种,它需要为保持各界面的状态,做很多持 ...
- Luffy之前端项目部署搭建
1. 搭建前端项目 1.1 创建项目目录 cd 项目目录 vue init webpack lufei 根据需要在生成项目时,我们选择对应的选项, 效果: 根据上面的提示,我们已经把vue项目构建好了 ...
- 『MXNet』第九弹_分类器以及迁移学习DEMO
解压文件命令: with zipfile.ZipFile('../data/kaggle_cifar10/' + fin, 'r') as zin: zin.extractall('../data/k ...
- Spring boot(四)thymeleaf使用介绍
在上篇文章springboot(二):web综合开发中简单介绍了一下thymeleaf,这篇文章将更加全面详细的介绍thymeleaf的使用.thymeleaf 是新一代的模板引擎,在spring4. ...
- atom - Emmet插件使用,代码快速填写
参考转载:http://www.hangge.com/blog/cache/detail_1537.html 用法: 输入:ul>li*6 接着按:tab键 常用语法: 1.后代>: ...
- 2017-6-5/MySQL分库分表
分库分表,顾名思义,就是把原本存储于一个库一张表的数据分块存储到多个库多张表上.对于大型互联网应用来说,当一张表的数据量达到百万.千万时,数据库每执行一次查询所花的时间会变多,并且数据库面临着极高的并 ...
- ThinkPHP3自动加载公共函数文件
7d 根目录 ├─Application 应用目录 │ ├─Common 公共模块 │ │ ├─Common 公共函数文件目录 │ │ │ ├─index.html │ │ ├─Config 配置文件 ...
- [CodeForces - 614D] D - Skills
D - Skills Lesha plays the recently published new version of the legendary game hacknet. In this ver ...
- 四、触发器(Trigger)
一.触发器 有点类似AOP里的拦截器,触发器不能传递参数,也不能输出参数,也不能显式调用,只有当满足触发器条件的时候Oracle会自动调用. 触发器: 1.语句级别的触发器:CRUD操作 2.行级别的 ...
- 彻底理解MapReduce shuffle过程原理
彻底理解MapReduce shuffle过程原理 MapReduce的Shuffle过程介绍 Shuffle的本义是洗牌.混洗,把一组有一定规则的数据尽量转换成一组无规则的数据,越随机越好.MapR ...