给定长度为 n 的序列 a1,a2,⋯,an 。
你需要回答多次询问,每次询问会给出一个数字 k ,请问序列中所有数字或 k 之和减去所有数字与 k 之和是多少,即求 ∑ni=1ai|k−∑ni=1ai&k 。
第一行输入一个整数 n 。
第二行输入 n 个整数 a1,a2,⋯,an 。
第三行输入一个整数 q ,表示询问次数。
接下来 q 行,每行输入一个整数 k 。
对于每次询问,输出一行一个整数,表示答案。
5
1 2 3 4 5
5
1
2
3
4
5
样例输出
14
17
16
19
18
对于 30%
的数据,保证 n,q≤1000 。 对于 100% 的数据,保证 1≤n,q≤5×105,1≤ai,k≤109 。
给定长度为 n 的序列 a1,a2,⋯,an 。
你需要回答多次询问,每次询问会给出一个数字 x ,你需要找到序列中小于等于 x 的数字中数位和最大的数字,或大于等于 x 的数字中数位和最小的数字。
第一行输入一个整数 n 。
第二行输入 n 个整数 a1,a2,⋯,an 。
第三行输入一个整数 q ,表示询问次数。
接下来 q 行,每行输入两个整数 op,x ,若 op=1 ,表示你需要找到序列中小于等于 x 的数字中数位和最大的数字,若 op=2 ,表示你需要找到大于等于 x 的数字中数位和最小的数字。
数据保证每次询问一定有解。
对于每次询问,输出一行一个整数,表示答案。对于 op=1 ,若存在多个满足条件的数位和最大的数字,输出值最大的那个,对于 op=2 ,若存在多个满足条件的数位和最小的数字,输出值最小的那个。
10
22 75 26 45 72 81 47 29 97 2
10
1 32
2 47
2 34
2 61
1 17
1 82
1 39
2 96
2 45
2 77
29
72
45
72
2
75
29
97
45
81
对于 30% 的数据,保证 n,q≤1000 。
对于 100% 的数据,保证 1≤n,q≤5×105,1≤ai,x≤109,1≤op≤2 。
#include<bits/stdc++.h>
using namespace std;
const int N = 5e5 + 10;
int n , q , a[N] , b[N] , s[N];
int check(int x) {
int sum = 0;
while (x)
sum += x % 10 , x /= 10;
return sum;
}
int node(int x) {
int l = 0 , r = n + 1;
while (l < r) {
int mid = (l + r + 1) / 2;
if (a[mid] <= x)
l = mid;
else
r = mid - 1;
}
for (int i = 1 ; i <= n ; i ++)
b[i] = check(a[i]);
s[1] = b[1];
for (int i = 1 ; i <= l ; i ++)
s[i] = max(s[i - 1] , b[i]);
return a[l];
}
int node1(int x){
int l = 0 , r = n;
while (l < r) {
int mid = (l + r) / 2;
if (a[mid] < x)
l = mid + 1;
else
r = mid;
}
for (int i = 1 ; i <= n ; i ++)
b[i] = check(a[i]);
s[1] = b[1];
for (int i = 1 ; i <= l ; i ++)
s[i] = min(s[i - 1] , b[i]);
return a[l];
}
int main() {
scanf("%d", &n);
for (int i = 1 ; i <= n ; i ++)
scanf("%d", &a[i]);
sort(a + 1, a + n + 1);
scanf("%d", &q);
while(q --){
int op , x;
scanf("%d%d", &op, &x);
if (op == 1)
printf("%d\n" , node(x));
else
printf("%d\n" , node1(x));
}
return 0;
}