题目分析:保存离每个点K近的数的下标,然后暴力更新即可。
代码如下:
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;
#define REP( i , a , b ) for ( int i = a ; i < b ; ++ i )
#define REV( i , a , b ) for ( int i = a ; i >= b ; -- i )
#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define CLR( a , x ) memset ( a , x , sizeof a )
#define CPY( a , x ) memcpy ( a , x , sizeof a )
#define s1 o * 4 + 1
#define s2 o * 4 + 2
#define s3 o * 4 + 3
#define s4 o * 4 + 4
#define Lower_Left s1 , lx , mx , ly , my
#define Upper_Left s2 , lx , mx , my + 1 , ry
#define Lower_Right s3 , mx + 1 , rx , ly , my
#define Upper_Right s4 , mx + 1 , rx , my + 1 , ry
#define midx ( ( lx + rx ) >> 1 )
#define midy ( ( ly + ry ) >> 1 )
#define root 0 , 1 , n , 1 , 1000
const int MAXN = 100005 ;
const int MAXE = 1000005 ;
struct Node {
int x , idx ;
double v ;
Node () {}
Node ( int x , int idx ) : x ( x ) , idx ( idx ) {}
} p[MAXN] , S[MAXN] ;
struct Edge {
int v , n ;
Edge () {}
Edge ( int v , int n ) : v ( v ) , n ( n ) {}
} E[MAXE] ;
int H[MAXN] , cntE ;
int top ;
int n , m , k ;
void clear () {
cntE = 0 ;
CLR ( H , -1 ) ;
}
void addedge ( int u , int v ) {
E[cntE] = Edge ( v , H[u] ) ;
H[u] = cntE ++ ;
}
int cmp1 ( const Node& a , const Node& b ) {
if ( a.x != b.x ) return a.x < b.x ;
return a.idx < b.idx ;
}
int cmp2 ( const Node& a , const Node& b ) {
return a.idx < b.idx ;
}
void solve () {
int u ;
double ans = 0 ;
clear () ;
scanf ( "%d%d%d" , &n , &m , &k ) ;
k = min ( n - 1 , k ) ;
FOR ( i , 1 , n ) {
scanf ( "%d%lf" , &p[i].x , &p[i].v ) ;
p[i].idx = i ;
}
sort ( p + 1 , p + n + 1 , cmp1 ) ;
FOR ( i , 1 , n ) {
int L = i - 1 , R = i + 1 ;
top = 0 ;
REP ( j , 0 , k ) {
if ( L && R <= n ) {
if ( p[i].x - p[L].x == p[R].x - p[i].x ) {
if ( p[L].idx < p[R].idx ) addedge ( p[i].idx , p[L --].idx ) ;
else addedge ( p[i].idx , p[R ++].idx ) ;
}
else if ( p[i].x - p[L].x < p[R].x - p[i].x ) addedge ( p[i].idx , p[L --].idx ) ;
else addedge ( p[i].idx , p[R ++].idx ) ;
}
else if ( L ) addedge ( p[i].idx , p[L --].idx ) ;
else addedge ( p[i].idx , p[R ++].idx ) ;
}
}
sort ( p + 1 , p + n + 1 , cmp2 ) ;
while ( m -- ) {
scanf ( "%d" , &u ) ;
double val = 0 ;
for ( int i = H[u] ; ~i ; i = E[i].n ) val += p[E[i].v].v ;
p[u].v = val / k ;
ans += val / k ;
}
printf ( "%.6f\n" , ans ) ;
}
int main () {
int T ;
scanf ( "%d" , &T ) ;
while ( T -- ) solve () ;
return 0 ;
}