ccf 201709-5 除法 java
2018-03-13 22:53
176 查看
问题描述
小葱喜欢除法,所以他给了你N个数a1, a2, ⋯, aN,并且希望你执行M次操作,每次操作可能有以下两种:
给你三个数l, r, v,你需要将al, al+1, ⋯, ar之间所有v的倍数除以v。
给你两个数l, r,你需要回答al + al+1 + ⋯ + ar的值是多少。
输入格式
第一行两个整数N, M,代表数的个数和操作的次数。
接下来一行N个整数,代表N个数一开始的值。输出格式
对于每一次的第二种操作,输出一行代表这次操作所询问的值。
样例输入
2
3
4
5
样例输出
2
评测用例规模与约定
对于30%的评测用例,1 ≤ N, M ≤ 1000;
对于另外20%的评测用例,第一种操作中一定有l = r;
对于另外20%的评测用例,第一种操作中一定有l = 1 , r = N;
对于100%的评测用例,1 ≤ N, M ≤ 105,0 ≤ a1, a2, ⋯, aN ≤ 106, 1 ≤ v ≤ 106, 1 ≤ l ≤ r ≤ N。import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int N = scanner.nextInt();//n个数
int[] nums = new int[N+1];
long[] treeSum
4000
= new long[N+1];
int m = scanner.nextInt();//m次操作
for (int i = 1; i <=N; i++) {
nums[i] = scanner.nextInt();
add(treeSum,i,nums[i]);//构造树状数组
}
for (int i = 0; i < m; i++) {
int option = scanner.nextInt();
if (option==1){
int L =scanner.nextInt();
int r =scanner.nextInt();
int v =scanner.nextInt();
if (v!=1){//特别重要,没有这个判断会超时,只能得50分
for (int j = L; j <=r; j++) {
if(nums[j]>=v && nums[j]%v==0){
int value = nums[j] -nums[j]/v;
nums[j] = nums[j]/v;
add(treeSum,j,-value);
}
}
}
}else if(option==2){
int L = scanner.nextInt();
int r = scanner.nextInt();
long count = getSum(treeSum,r)-getSum(treeSum,L-1);
System.out.println(count);
}
}
}
private static long getSum(long[] treeNums, int n) {
long sum = 0 ;
while (n>0){
sum += treeNums
;
n -=lowbit(n);
}
return sum;
}
private static void add(long[] treeNums, int index,int value) {
if (index>0){
for (int i = index; i<=treeNums.length-1 ; i+=lowbit(i)) {
treeNums[i] +=value;
}
}
}
private static int lowbit(int value) {//lowbit(i) = 2^k
return value & (-value);
}
}
小葱喜欢除法,所以他给了你N个数a1, a2, ⋯, aN,并且希望你执行M次操作,每次操作可能有以下两种:
给你三个数l, r, v,你需要将al, al+1, ⋯, ar之间所有v的倍数除以v。
给你两个数l, r,你需要回答al + al+1 + ⋯ + ar的值是多少。
输入格式
第一行两个整数N, M,代表数的个数和操作的次数。
接下来一行N个整数,代表N个数一开始的值。输出格式
对于每一次的第二种操作,输出一行代表这次操作所询问的值。
样例输入
5 3 1 2 3 4 5 2 1 5 1 1 3 2 2 1 51
2
3
4
5
样例输出
15 141
2
评测用例规模与约定
对于30%的评测用例,1 ≤ N, M ≤ 1000;
对于另外20%的评测用例,第一种操作中一定有l = r;
对于另外20%的评测用例,第一种操作中一定有l = 1 , r = N;
对于100%的评测用例,1 ≤ N, M ≤ 105,0 ≤ a1, a2, ⋯, aN ≤ 106, 1 ≤ v ≤ 106, 1 ≤ l ≤ r ≤ N。import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int N = scanner.nextInt();//n个数
int[] nums = new int[N+1];
long[] treeSum
4000
= new long[N+1];
int m = scanner.nextInt();//m次操作
for (int i = 1; i <=N; i++) {
nums[i] = scanner.nextInt();
add(treeSum,i,nums[i]);//构造树状数组
}
for (int i = 0; i < m; i++) {
int option = scanner.nextInt();
if (option==1){
int L =scanner.nextInt();
int r =scanner.nextInt();
int v =scanner.nextInt();
if (v!=1){//特别重要,没有这个判断会超时,只能得50分
for (int j = L; j <=r; j++) {
if(nums[j]>=v && nums[j]%v==0){
int value = nums[j] -nums[j]/v;
nums[j] = nums[j]/v;
add(treeSum,j,-value);
}
}
}
}else if(option==2){
int L = scanner.nextInt();
int r = scanner.nextInt();
long count = getSum(treeSum,r)-getSum(treeSum,L-1);
System.out.println(count);
}
}
}
private static long getSum(long[] treeNums, int n) {
long sum = 0 ;
while (n>0){
sum += treeNums
;
n -=lowbit(n);
}
return sum;
}
private static void add(long[] treeNums, int index,int value) {
if (index>0){
for (int i = index; i<=treeNums.length-1 ; i+=lowbit(i)) {
treeNums[i] +=value;
}
}
}
private static int lowbit(int value) {//lowbit(i) = 2^k
return value & (-value);
}
}
树状数组彻底入门
https://www.cnblogs.com/hsd-/p/6139376.html相关文章推荐
- CCF CSP认证 题解:201709-5 除法(Java语言原创)
- CCF 201709-5 除法 Java
- CCF CSP 201709-2 公共钥匙盒(Java-100分)
- CCF 201709-1 打酱油(Java)
- CCF 201709-5 除法
- ccf 201709-4 通信网络 java 100分
- CCF-CSP 通信网络 JAVA 201709-4 100分
- CCF CSP认证 题解:201709-2 公共钥匙盒(Java语言原创)
- CCF 201709-2 公共钥匙盒 Java
- CCF CSP 201709-1 打酱油(Java-100分)
- CCF 201709-2 公共钥匙盒(Java)
- 201709-5 除法 ccf
- CCF CSP认证 题解:201709-4 通信网络 DFS(Java语言原创)
- ccf 201709-5 除法
- CCF 201709-5 除法 c++题解
- CCF 201709-3 JSON查询(Java)
- CCF CSP 公共钥匙盒 JAVA 201709-2 100分
- CCF 201709-4 通信网络 Java
- CCF 201709-3 Json查询 Java
- CCF考试——201709-5除法