大学生程序设计邀请赛(华东师范大学)-D题(线段树+随机化)

来源:互联网 发布:政务数据共享开放平台 编辑:程序博客网 时间:2024/06/05 20:48

题解思路,更新每一个点最多可以传染到哪个地方然后更新线段树,更新结点的时候不能根据x坐标从左往右更新要随机更新因为
如果数据是:
1 3
3 1…..后面省略 这样更新我更新完第一个位置还要再更新一下第二个位置但是如果先更新第二个位置的话更新第一位置的话就可以少更新2之前的位置因为数据位置我们要打乱随机更新
题目链接

#include<iostream>#include<algorithm>#include<queue>#include<cstring>#include<cstdio>#define rec(i,a,n) for(i = a; i <= n; i++)#define dec(i,a,n) for(i = n; i >= a; i--)#define ls 2*i#define rs 2*i+1#define mid (L+R)/2#define lson ls,L,mid#define rson rs,mid+1,Rusing namespace std;const int mx = 1e5+5;pair<int,int>T[mx<<2];struct node{    int l,r;    int x;    int pos;    bool operator<(node a)const{        return x<a.x;    }}a[mx];void built(int i,int L,int R){    if(L == R){        T[i].first = a[L].l;        T[i].second = a[L].r;        return;    }    built(lson);    built(rson);    T[i].first = min(T[ls].first,T[rs].first);    T[i].second = max(T[ls].second,T[rs].second);}pair<int,int> calc(int i,int L,int R,int l,int r){    if( l <= L && R <= r)        return T[i];    if(l > mid) return calc(rson,l,r);    else if(r <= mid)   return calc(lson,l,r);    else{        pair<int,int>sum1 = calc(lson,l,mid);        pair<int,int>sum2 = calc(rson,mid+1,r);        pair<int,int>sum;        sum.first = min(sum1.first,sum2.first);        sum.second = max(sum1.second,sum2.second);        return sum;    }}void update(int i,int L,int R,int t,int l,int r){    if(L == R){        T[i].first = l;        T[i].second = r;        return;    }    if(t > mid) update(rson,t,l,r);    else  update(lson,t,l,r);    T[i].first = min(T[ls].first,T[rs].first);    T[i].second = max(T[ls].second,T[rs].second);}pair<int,int> query(int t,int L,int R){    pair<int,int> p1{a[t].l,a[t].r},p2;    while(1){        p2 = calc(1,L,R,p1.first,p1.second); //一直更新         if(p1.second == p2.second && p1.first == p2.first) //判断是否已经更新不了             break;        p1.first = min(p1.first,p2.first);        p1.second = max(p2.second,p1.second);    }    update(1,L,R,t,p1.first,p1.second);    return p1;}int ans[mx],px[mx];int main(){    int i,n,d;    scanf("%d",&n);    rec(i,1,n){        scanf("%d%d",&a[i].x,&d);        a[i].pos = i;        px[i] = a[i].x;        a[i].l = a[i].x - d;        a[i].r = a[i].x + d;    }    sort(px+1,px+1+n);    sort(a+1,a+1+n);    rec(i,1,n){        a[i].l = lower_bound(px+1,px+1+n,a[i].l)-px;        a[i].r = upper_bound(px+1,px+1+n,a[i].r)-px;        a[i].r -= 1;    }    built(1,1,n);    vector<int>vec;    vec.push_back(0);    for(int i = 1; i <= n; i ++) {        vec.push_back(i);    }    random_shuffle(vec.begin()+1, vec.end()); //打乱更新位置     rec(i,1,n){        int t = vec[i];        pair<int,int>p = query(t,1,n);        ans[a[t].pos] = p.second - p.first +1; //题目要求是原位输出不是排序好的     }    rec(i,1,n)        printf("%d%c",ans[i],i == n?'\n':' ');    return 0;}
阅读全文
0 0
原创粉丝点击