1)二分
Points in Segments 大意:在单调的数组中计算符合标准的数的个数。
点击打开链接
#include<stdio.h>
int a[100009];
int p1 , p2 ;
int fen1(int size,int p1){
int l = 0 , r = size - 1 ;
int g = -1;
while( l<=r ){ //找到大于等于p1的数组下标;
int mid = r - ( r - l )/2 ;
if ( a[mid] < p1 ) l = mid + 1;
else {
r = mid - 1;
g = mid; //记录下符合标准的最小下标。
}
}
return g; //如果返回值为-1,说明p1比数组中的数都大,所以数组中一定没有符合标准的数。
}
int fen2(int size,int p2){
int l = 0 , r = size - 1 ;
int g = -1;
while( l<=r ){ //找到小于等于p2的数组下标
int mid = r - ( r - l )/2 ;
if (a[mid] > p2 ) {
r = mid - 1;
}
else {
l = mid + 1;
g = mid; //记录下符合标准的最大下标。
}
}
return g;
}
int main(){
int T;
scanf("%d", &T);
for(int k = 1; k <= T; k++ ){
printf("Case %d:\n", k );
int n , m ;
scanf("%d %d", &n, &m );
for(int i = 0; i < n ; i++ ){
scanf("%d", &a[i] );
}
while(m--){
scanf("%d %d", &p1, &p2);
if((fen1( n , p1 )!=-1)&&(fen2( n , p2 )!=-1)){
printf("%d\n", fen2( n , p2 ) - fen1( n , p1 ) + 1);
}
else
printf("0\n");
}
}
}
Values whose Sum is 0 大意:有四个数组,从中分别选择一个数,计算四个数和为0的个数。
#include<cstdio>
#include<algorithm>
using namespace std;
int ab[16000000],cd[16000000];
int p;
int fen(int size,int p){
int l = 0 , r = size - 1 ;
int g = 0;
while( l<=r ){
int mid = r - ( r - l )/2 ;
if ( cd[mid] + p==0 ){ //计算所有和为0的个数。
for(int i = mid;i<=r;i++){
if(cd[i] + p!=0) break;
g++;
//printf("%d %d\n",cd[i],p);
}
for(int i = mid-1;i>=l;i--){
if(cd[i] + p!=0) break;
g++;
//printf("%d %d\n",cd[i],p);
}
return g;
}
else if ( cd[mid] + p < 0 ) l = mid + 1;
else if ( cd[mid] + p > 0 ) r = mid - 1;
}
// printf("***%d\n",g);
return g;
}
int main(){
int n;
scanf("%d", &n );
int a[4000],b[4000],c[4000],d[4000];
for(int i = 0; i < n ; i++ ){
scanf("%d%d%d%d", &a[i], &b[i], &c[i], &d[i]);
}
int ij = 0;
for(int i = 0; i < n; i++ ){
for(int j = 0; j < n; j++ ){
ab[ij] = a[i] + b[j];
cd[ij] = c[i] + d[j];
ij++; //个数
}
}
int ans = 0;
sort(cd,cd+ij);
for(int i = 0; i < ij; i++ ){ //对ab数组中的每一个数进行二分。
ans += fen( ij , ab[i] );
}
printf("%d\n",ans);
}