ACwing-1210. 连号区间数
小明这些天一直在思考这样一个奇怪而有趣的问题:
在 1∼N 的某个排列中有多少个连号区间呢?
这里所说的连号区间的定义是:
如果区间 [L,R] 里的所有元素(即此排列的第 L 个到第 R 个元素)递增排序后能得到一个长度为 R−L+1 的“连续”数列,则称这个区间连号区间。
当 N 很小的时候,小明可以很快地算出答案,但是当 N 变大的时候,问题就不是那么简单了,现在小明需要你的帮助。
输入格式
第一行是一个正整数 N,表示排列的规模。
第二行是 N 个不同的数字 Pi,表示这 N 个数字的某一排列。
输出格式
输出一个整数,表示不同连号区间的数目。
数据范围
1≤N≤10000,
1≤Pi≤N
输入样例1:
4
3 2 4 1
输出样例1:
7
输入样例2:
5
3 4 2 5 1
输出样例2:
9
样例解释
第一个用例中,有 7 个连号区间分别是:[1,1],[1,2],[1,3],[1,4],[2,2],[3,3],[4,4]
第二个用例中,有 9 个连号区间分别是:[1,1],[1,2],[1,3],[1,4],[1,5],[2,2],[3,3],[4,4],[5,5]
ps : 第二行是 N 个不同的数字 Pi,表示这 N 个数字的某一排列。 和 1∼N 的某个排列中,代表此中的数字不会相同,故最大值和最小值如果等于数字的个数即必定是连续的;
import java.util.Arrays;
import java.util.Scanner;
public class Main {
static Scanner sc = new Scanner(System.in);
public static void main(String[] args) {
// TODO Auto-generated method stub
int n = sc.nextInt();
int[] a = new int[10005];
for(int i = 0; i < n; i++) {
a[i] = sc.nextInt();
}
int ans = 0;
for(int i = 0; i < n; i++) {
int min = n + 1,max = 0;
for(int j = i; j < n; j++) {
max = Math.max(max, a[j]);
min = Math.min(min, a[j]);
if(j - i == max - min)ans++;
}
}
System.out.println(ans);
}
}
1236. 递增三元组
给定三个整数数组
A=[A1,A2,…AN],
B=[B1,B2,…BN],
C=[C1,C2,…CN],
请你统计有多少个三元组 (i,j,k) 满足:
1≤i,j,k≤N
Ai<Bj<Ck
输入格式
第一行包含一个整数 N。
第二行包含 N 个整数 A1,A2,…AN。
第三行包含 N 个整数 B1,B2,…BN。
第四行包含 N 个整数 C1,C2,…CN。
输出格式
一个整数表示答案。
数据范围
1≤N≤105,
0≤Ai,Bi,Ci≤105
输入样例:
3
1 1 1
2 2 2
3 3 3
输出样例:
27
import java.io.BufferedInputStream;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Arrays;
import java.util.Scanner;
public class Main {
static Scanner sc = new Scanner(new BufferedInputStream(System.in));
static BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));
public static void main(String[] args) throws IOException {
int n = sc.nextInt();
int[] a = new int[100005];int[] b = new int[100005];int[] c = new int[100005];
int[] cnt = new int[100005];int[] s = new int[100005];
int[] as = new int[100005];int[] cs = new int[100005];
for(int i = 0; i < n; i++)a[i] = sc.nextInt() + 1;
for(int i = 0; i < n; i++)b[i] = sc.nextInt() + 1;
for(int i = 0; i < n; i++)c[i] = sc.nextInt() + 1;
//cnt[i] 代表 值等于 i 的个数,也就是说 cnt里面记录的是 a[i]大小的个数
for(int i = 0; i < n; i++)cnt[a[i]] ++;
//s[i]代表 0-i的个数,也就是说 a[i]中小于 i的 个数
for(int i = 1; i < 100005; i++)s[i] = s[i - 1] + cnt[i];
for(int i = 0; i < n; i++)as[i] = s[b[i]-1];
Arrays.fill(cnt, 0);Arrays.fill(s, 0);
//c同理
for(int i = 0; i < n; i++)cnt[c[i]] ++;
for(int i = 1; i < 100005; i++)s[i] = s[i - 1] + cnt[i];
for(int i = 0; i < n; i++)cs[i] = s[100004] - s[b[i]];
long ans = 0;
//对于每一个b[i] 只需知道比b[i]小的 a[i]有多少个 和 比 b[i]大的 c[i]有多少个相乘,即为答案;
for(int i = 0; i < n; i++)ans += (long)as[i] * (long)cs[i];
out.write(ans + "\n");
out.flush();
}
}
二分:
import java.io.BufferedInputStream;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Arrays;
import java.util.Scanner;
public class Main {
static Scanner sc = new Scanner(