B. Forming Triangles
题意:给你n个数字,每个数字代表的是2的x次幂,问能组成多少个不同的三角形。
题解:这个题我一眼看首先想到
,那么首先
,肯定不能计算出来,那么很明显,如果有两个相同数字以上,才能产生贡献,首先考虑两个相同的数字情况,那明显就是剩下小于x的数字乘上
,再加上
。i从0开始枚举,求出所有贡献即可。
代码:
#include<bits/stdc++.h>
using namespace std ;
typedef long long ll ;
typedef pair < ll , ll > PII ;
const int maxn = 1e6 + 7 ;
inline ll read(){
ll x = 0 , f = 1;
char c = getchar() ;
while(c > '9' || c < '0'){
if(c == '-')
f = -1 ;
c = getchar() ;
}
while(c >= '0' && c <= '9'){
x = x * 10 + c - '0' ;
c = getchar() ;
}
return x * f ;
}
ll t , n , m , xx , yy , x2 , y2 , a[maxn] , b[maxn] , c[maxn] ;
char s[maxn] , S[maxn] , ss[maxn] ;
ll f[maxn][3] ;
bool check(ll x , ll mid){
if(a[x] >= a[mid + 1] || a[mid] >= a[mid + 1]){
return 1 ;
}
return 0 ;
}
void solve(){
n = read() ;
for(int i = 1 ; i <= n ; i ++){
a[i] = read() ;
}
sort(a + 1 , a + n + 1) ;
map < ll , ll > mp ;
for(int i = 1 ; i <= n ; i ++){
mp[a[i]] ++ ;
}
ll Ans = 0 , cnt = 0 ;
for(auto it : mp){
ll res = it.second ;
Ans += ((res * (res - 1) * (res - 2) / 6ll) + ((res * (res - 1)) / 2ll) * cnt) ;
cnt += it.second ;
}
cout << Ans << endl ;
}
int main(){
t = read() ;
while(t --){
solve() ;
}
return 0 ;
}
C. Closest Cities
题意:每个点都有一个离自己最近距离的点,如果x->y,y是x最近的点,则消耗金币1。否则就消耗金币
。有m组查询,查询从x->y最小的消耗金币数量是多少。
题解:这题只需要处理从
,每次处理向右或向左的金币数字,就比如,枚举
, 如果
,向右消耗金币就是向右消耗金币数量就是
,否则向右消耗金币就是1。再枚举一遍向左的,用前缀和处理出来,每次
查询即可,需要处理一些边界和数字的小细节,详细请见代码。
代码:
#include<bits/stdc++.h>
using namespace std ;
typedef long long ll ;
typedef pair < ll , ll > PII ;
const int maxn = 1e6 + 7 ;
inline ll read(){
ll x = 0 , f = 1;
char c = getchar() ;
while(c > '9' || c < '0'){
if(c == '-')
f = -1 ;
c = getchar() ;
}
while(c >= '0' && c <= '9'){
x = x * 10 + c - '0' ;
c = getchar() ;
}
return x * f ;
}
ll t , n , m , xx , yy , x2 , y2 , a[maxn] , sum[maxn] , Sum[maxn] ;
char s[maxn] , S[maxn] , ss[maxn] ;
ll f[maxn][3] ;
bool check(ll x , ll mid){
if(a[x] >= a[mid + 1] || a[mid] >= a[mid + 1]){
return 1 ;
}
return 0 ;
}
void solve(){
n = read() ;
for(int i = 1 ; i <= n ; i ++){
a[i] = read() ;
}
for(int i = 1 ; i <= n ; i ++){
sum[i] = Sum[i] = 0 ;
}
sum[1] = 1 ;
for(int i = 2 ; i <= n - 1 ; i ++){
if(abs(a[i] - a[i - 1]) < abs(a[i] - a[i + 1])){
sum[i] = abs(a[i] - a[i + 1]) ;
continue ;
}
if(abs(a[i] - a[i - 1]) > abs(a[i] - a[i + 1])){
sum[i] = 1 ;
continue ;
}
}
Sum[n] = 1 ;
for(int i = n - 1 ; i >= 2 ; i --){
if(abs(a[i] - a[i - 1]) > abs(a[i] - a[i + 1])){
Sum[i] = abs(a[i] - a[i - 1]) ;
continue ;
}
if(abs(a[i] - a[i - 1]) < abs(a[i] - a[i + 1])){
Sum[i] = 1 ;
continue ;
}
}
Sum[n + 1] = 0 ;
for(int i = n ; i >= 1 ; i --){
Sum[i] = Sum[i + 1] + Sum[i] ;
}
for(int i = 1 ; i <= n - 1 ; i ++){
sum[i] = sum[i - 1] + sum[i] ;
}
m = read() ;
for(int i = 1 ; i <= m ; i ++){
ll st , sd ;
st = read() ;
sd = read() ;
if(st >= sd){
cout << Sum[sd + 1] - Sum[st + 1] << endl ;
}
else{
cout << sum[sd - 1] - sum[st - 1] << endl ;
}
}
}
int main(){
t = read() ;
while(t --){
solve() ;
}
return 0 ;
}