您的位置:首页 > 其它

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

2017-05-18 17:55 323 查看
题解思路,更新每一个点最多可以传染到哪个地方然后更新线段树,更新结点的时候不能根据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,R
using 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐