直接按题意模拟就好了,注意index指的是输入进来时候的数组下标。
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define INF 1000000005
using namespace std;
struct NODE
{
int x,id;
double v;
}node[100005],node2[100005];
bool cmp(NODE a,NODE b)
{
return a.x<b.x;
}
int check(int x,int l,int r)
{
int mid;
while(l<=r){
mid=(l+r)>>1;
if(node[mid].x==x) return mid;
if(node[mid].x>x) r=mid-1;
else l=mid+1;
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--){
int n,m,k,i;
scanf("%d%d%d",&n,&m,&k);
for(i=1;i<=n;i++){
scanf("%d%lf",&node[i].x,&node[i].v);
node[i].id=i;
node2[i].x=node[i].x;
node2[i].v=node[i].v;
}
sort(node+1,node+n+1,cmp);
int indx;
double ans=0;
double sum=0;
for(i=1;i<=m;i++){
scanf("%d",&indx);
indx=check(node2[indx].x,1,n);
int left=indx-1,right=indx+1,tmp1,tmp2,ct=0;
sum=0;
while(ct<k){
tmp1=INF;
tmp2=INF;
if(left>0){
tmp1=node[indx].x-node[left].x;
}
if(right<=n){
tmp2=node[right].x-node[indx].x;
}
if(tmp1<tmp2){
sum+=node[left].v;
left--;
}
else if(tmp1>tmp2){
sum+=node[right].v;
right++;
}
else{
if(node[left].id<node[right].id){
sum+=node[left].v;
left--;
}
else{
sum+=node[right].v;
right++;
}
}
ct++;
}
node[indx].v=sum/k;
ans+=sum/k;
}
printf("%.6lf\n",ans);
}
return 0;
}