POJ 3667 线段树 区间合并经典题目

来源:互联网 发布:淘宝耳饰 知乎 编辑:程序博客网 时间:2024/05/16 09:55

区间染色  二分逼近查找

区间合并部分很简单  query方式稍有不同 分别对每种情况处理即可


#include "stdio.h"#include "string.h"#include "stdlib.h"#include "math.h"struct comp{int l,r,mid,lazy;int lsum,rsum,sum;} data[300001];int key;int max(int a,int b){if (a<b) return b;else return a;}void build(int l,int r,int k){data[k].l=l;data[k].r=r;data[k].mid=(l+r)/2;data[k].lazy=-1;data[k].lsum=data[k].rsum=data[k].sum=data[k].r-data[k].l+1;if (l==r) return ;build(l,data[k].mid,k*2);build(data[k].mid+1,r,k*2+1);}void Pushdown(int k){int ll,rr;if (data[k].l==data[k].r) return ;if (data[k].lazy!=-1){data[k*2].lazy=data[k*2+1].lazy=data[k].lazy;ll=data[k*2].r-data[k*2].l+1;rr=data[k*2+1].r-data[k*2+1].l+1;if (data[k].lazy==1){data[k*2].lsum=data[k*2].rsum=data[k*2].sum=ll;data[k*2+1].lsum=data[k*2+1].rsum=data[k*2+1].sum=rr;}else {data[k*2].lsum=data[k*2].rsum=data[k*2].sum=0;data[k*2+1].lsum=data[k*2+1].rsum=data[k*2+1].sum=0;}data[k].lazy=-1;return ;}}void Pushup(int k){int ll,rr;ll=data[k*2].r-data[k*2].l+1;rr=data[k*2+1].r-data[k*2+1].l+1;data[k].lsum=data[k*2].lsum;if (data[k].lsum==ll) data[k].lsum+=data[k*2+1].lsum;data[k].rsum=data[k*2+1].rsum;if (data[k].rsum==rr) data[k].rsum+=data[k*2].rsum;data[k].sum=max(max(data[k*2].sum,data[k*2+1].sum),data[k*2].rsum+data[k*2+1].lsum);}int  query(int n,int k){Pushdown(k);if (data[k*2].lsum>=n) return data[k*2].l; // 在左子树最左直接输出位置else if (data[k*2].sum>=n) return query(n,k*2); // 在左子树中查询elseif (data[k*2].rsum+data[k*2+1].lsum>=n) return  data[k*2].r-data[k*2].rsum+1; // 在中间直接输出位置else if (data[k*2+1].sum>=n) return query(n,k*2+1); // 在右子树中查询else return 0; }void insert(int l,int r,int k){if (data[k].l==l && data[k].r==r){data[k].lsum=data[k].rsum=data[k].sum=0;data[k].lazy=0;return ;}Pushdown(k);if (r<=data[k].mid) insert(l,r,k*2);else if (l>data[k].mid) insert(l,r,k*2+1);else {insert(l,data[k].mid,k*2);insert(data[k].mid+1,r,k*2+1);}Pushup(k);}void update(int l,int r,int k){if (data[k].l==l && data[k].r==r){data[k].lsum=data[k].rsum=data[k].sum=data[k].r-data[k].l+1;data[k].lazy=1;return ;}Pushdown(k);if (r<=data[k].mid) update(l,r,k*2);else if (l>data[k].mid) update(l,r,k*2+1);else {update(l,data[k].mid,k*2);update(data[k].mid+1,r,k*2+1);}Pushup(k);}int main(){int n,m,op,x,y;while (scanf("%d%d",&n,&m)!=EOF){build(1,n,1);while (m--){scanf("%d",&op);if (op==1){scanf("%d",&x);key=query(x,1);printf("%d\n",key);if (key!=0) insert(key,key+x-1,1);}else {scanf("%d%d",&x,&y);update(x,x+y-1,1);}}}return 0;}



原创粉丝点击