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--------自定义控件 之 方法篇
前面简单的讲述了Android中自定义控件的理论和流程图,今天通过代码来详细的讲解一下其中的方法 首先先创建一个类 CircularView 继承于 View,之后实现构造方法(初始化步骤) publ ...
- jenkins+maven+git+tomcat+salt自动构建
jenkins 安装步骤 环境: centos7,jdk1.8.0,jenkins2.165,maven3.5.2 一. 安装配置java环境 JDK1.8下载地址:http://www.orac ...
- 如何阻止div中的子div触发div的事件
<div class="sideFrame" v-on:click="hideside"> <div class="sideFram ...
- 【洛谷p2822】组合数问题
(突然想 ??忘掉了wdt) (行吧那就%%%hmr) 组合数问题[传送门] (因为清明要出去培训数学知识所以一直在做数论) 组合数<=>杨辉三角形(从wz那拐来的技能 ...
- Appium移动自动化测试(一)----Appium的安装
前言: 我的环境为win10 64,安装过程请根据自己的电脑环境而定. 一.Appium安装 1.Appium官方网站:http://appium.io/下载windows版本的Appium; Eas ...
- python theading线程开发与加锁、信号量、事件等详解
线程有2种调用方式,如下: 直接调用 import threading import time def sayhi(num): #定义每个线程要运行的函数 print("running on ...
- Java 8 forEach
1. forEach and Map 1.1 通常这样遍历一个Map Map<String, Integer> items = new HashMap<>(); items.p ...
- 19. Remove Nth Node From End of List C++删除链表的倒数第N个节点
https://leetcode.com/problems/remove-nth-node-from-end-of-list/ 使用双指针法,可以仅遍历一次完成节点的定位 /** * Definiti ...
- 数据结构与算法之PHP实现二叉树的遍历
一.二叉树的遍历 以某种特定顺序访问树中所有的节点称为树的遍历,遍历二叉树可分深度优先遍历和广度优先遍历. 深度优先遍历:对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次.可以细分 ...
- PostgreSQL数据库单机扩展为流复制
primary:10.189.102.118 standby:10.189.100.195 1. 配置ssh互信机制 在primary主库执行 $ ssh-keygen -t rsa $ cp ~/. ...