一个二分里套一个二分就行了。。。。
#include <iostream> #include <queue> #include <stack> #include <map> #include <set> #include <bitset> #include <cstdio> #include <algorithm> #include <cstring> #include <climits> #include <cstdlib> #include <cmath> #include <time.h> #define maxn 100005 #define maxm 300005 #define eps 1e-10 #define mod 10000007 #define INF 2e9 #define lowbit(x) (x&(-x)) #define mp make_pair #define ls o<<1 #define rs o<<1 | 1 #define lson o<<1, L, mid #define rson o<<1 | 1, mid+1, R //typedef long long LL; typedef int LL; using namespace std; LL qpow(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base;base=base*base;b/=2;}return res;} LL powmod(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base%mod;base=base*base%mod;b/=2;}return res;} void scanf(int &__x){__x=0;char __ch=getchar();while(__ch==' '||__ch=='\n')__ch=getchar();while(__ch>='0'&&__ch<='9')__x=__x*10+__ch-'0',__ch = getchar();} LL gcd(LL _a, LL _b){if(!_b) return _a;else return gcd(_b, _a%_b);} // head struct point { int x, id; double v; }p[maxn]; double tree[maxn<<2]; int n, m, ql, qr, pp; int mpp[maxn]; double v; int cmp(point a, point b) { return a.x < b.x; } void read(void) { scanf("%d%d", &n, &m); for(int i = 1; i <= n; i++) scanf("%d%lf", &p[i].x, &p[i].v), p[i].id = i; sort(p+1, p+n+1, cmp); p[0].x = -INF, p[n+1].x = INF, p[n+1].id = INF, p[0].id = INF; for(int i = 1; i <= n; i++) mpp[p[i].id] = i; } int find1(int now, int k) { int bot = 0, top = n+1, mid, res; while(top >= bot) { mid = (top + bot) >> 1; if(p[mid].x >= k) res = mid, top = mid-1; else bot = mid+1; } return res; } int find2(int now, int k) { int bot = 0, top = n+1, mid, res; while(top >= bot) { mid = (top + bot) >> 1; if(p[mid].x > k) top = mid-1; else bot = mid+1, res = mid; } return res; } void search(int now, int k) { int bot = 1, top = 1000000000, mid, t1, t2; while(top >= bot) { mid = (top + bot) >> 1; t1 = find1(now, p[now].x - mid); t2 = find2(now, p[now].x + mid); int t = t2 - t1; if(t == k) { ql = t1, qr = t2; break; } if(t == k+1 && abs(p[t1].x - p[now].x) == abs(p[t2].x - p[now].x)) { if(p[t1].id > p[t2].id) ql = t1+1, qr = t2; else ql = t1, qr = t2-1; break; } if(t > k) top = mid-1; else bot = mid+1; } } void pushup(int o) { tree[o] = tree[ls] + tree[rs]; } void build(int o, int L, int R) { if(L == R) { tree[o] = p[L].v; return; } int mid = (L + R) >> 1; build(lson); build(rson); pushup(o); } double query(int o, int L, int R) { if(ql <= L && qr >= R) return tree[o]; int mid = (L + R) >> 1; double ans = 0; if(ql <= mid) ans += query(lson); if(qr > mid) ans += query(rson); return ans; } void updata(int o, int L, int R) { if(L == R) { tree[o] = v; return; } int mid = (L + R) >> 1; if(pp <= mid) updata(lson); else updata(rson); pushup(o); } void debug(void) { search(mpp[4], 2); printf("AA %d %d BB\n", ql, qr); } void work(void) { int id, k; double sum, ans = 0; build(1, 1, n); while(m--) { scanf("%d%d", &id, &k); id = mpp[id]; search(id, k); sum = query(1, 1, n); sum -= p[id].v; //printf("BBBBBBB %d %d\n", ql, qr); sum /= k; //printf("AAAA %f\n", sum); ans += sum; pp = id, v = sum, p[id].v = v; //printf("VCVVVVVVV %f\n", v); updata(1, 1, n); } printf("%.3f\n", ans); } int main(void) { int _; while(scanf("%d", &_)!=EOF) { while(_--) { read(); //debug(); work(); } } return 0; }