題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=5021
題目描述:在座標軸上有n 個位置,每個位置有一個值。有一個操作,每次求距離位置 i 最近的k 個最近的位置的平均值,替代當前位置的值,並且加入答案
解題思路:思路比較簡單,二分距離,然後再二分位置,求出距離位置i 最近的k 個點的區間[l ,r],然後用樹狀數組維護一下區間和就可以了
但是,有一個track就是!!! if there is a tie while choosing k-Nearest Neighbor, choose the one with the minimal index first,注意是下標,題目並沒有給下標,下標就是輸入的順序,又被坑一次。。。。長教訓了。。。
//#pragma comment(linker,"/STACK:102400000,102400000")
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<string>
#define ll long long
#define db double
#define PB push_back
#define lson k<<1
#define rson k<<1|1
using namespace std;
const int N = 100005;
const int INF = 1000000000;
struct node
{
int x,v,id;
bool operator < (const node &t) const
{
return x<t.x;
}
} a[N];
int pt[N];
int n;
void find_st_ed(int q,int dis,int &res1,int &res2)
{
int l=1,r=q;
while(l<=r)
{
int mid=(l+r)>>1;
if(a[q].x-a[mid].x<=dis)
{
res1=mid;
r=mid-1;
}else
{
l=mid+1;
}
}
l=q,r=n;
while(l<=r)
{
int mid=(l+r)>>1;
if(a[mid].x-a[q].x<=dis)
{
res2=mid;
l=mid+1;
}else
{
r=mid-1;
}
}
}
int k;
void find_lr(int q,int &res1,int &res2)
{
int l=1,r=INF;
while(l<=r)
{
int mid=(l+r)>>1;
int st,ed;
find_st_ed(q,mid,st,ed);
if(ed-st<k)
{
l=mid+1;
}else if(ed-st>k+1)
{
r=mid-1;
}else
{
if(ed-st==k)
{
}else
{
if(a[q].x-a[st].x==a[ed].x-a[q].x)
{
if(a[st].id<a[ed].id) ed--;
else st++;
}else if(a[q].x-a[st].x<a[ed].x-a[q].x)
ed--;
else st++;
}
res1=st,res2=ed;
return;
}
}
}
db tr[N];
int lowbit(int t)
{
return t&(-t);
}
void add(int i,db val)
{
for(;i<=n;tr[i]+=val,i+=lowbit(i));
}
db sum(int i)
{
db res(0.0);
for(;i>0;res+=tr[i],i-=lowbit(i));
return res;
}
int main()
{
#ifdef PKWV
freopen("in.in","r",stdin);
#endif // PKWV
int T;
scanf("%d",&T);
while(T--)
{
int m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d%d",&a[i].x,&a[i].v),a[i].id=i;
sort(a+1,a+n+1);
for(int i=1;i<=n;i++) pt[a[i].id]=i;
db ans=0.0;
for(int i=1;i<=n;i++) tr[i]=0.0;
for(int i=1;i<=n;i++) add(i,a[i].v);
while(m--)
{
int q;
scanf("%d%d",&q,&k);
q=pt[q];
int l,r;
find_lr(q,l,r);
db s=sum(r)-sum(l-1);
db t=sum(q)-sum(q-1);
db tmp=(s-t)/(db)k;
ans+=tmp;
add(q,tmp-t);
}
printf("%.3f\n",ans);
}
return 0;
}