BC D Revenge of kNN II hdu 5021

題目鏈接: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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章