3年没写线段树题了,今天帮小学弟水了棵线段树,想不到现在依然有看到Accepted的鸡冻哈哈哈

来源:互联网 发布:西门子s7200软件下载 编辑:程序博客网 时间:2024/04/29 07:57

题目大意:给一个区间1~10^10,然后Q个操作有更新,有询问,Q的范围是1~10^5,明显是一个离散化+区间更新的线段树水题传送门,这里更新需要注意lay的思想,也就是延迟更新,具体就是push down和push up操作,具体看代码;

#include <cstdio>#include <algorithm>#include <iostream>using namespace std;const int MAX=204002;int a[MAX*2];int op[MAX][3];struct node{  int l,r,ok;}tree[MAX*8];void build(int pos,int l,int r)  {    tree[pos].l=l;    tree[pos].r=r;    tree[pos].ok = a[tree[pos].r-1] - a[tree[pos].l-1]+1;    if(l==r)        return;    int mid=(l+r)>>1;    build(pos*2,l,mid);    build(pos*2+1,mid+1,r);    tree[pos].ok = tree[pos*2].ok+ tree[pos*2+1].ok;}void update(int pos,int l,int r){   if(l<=tree[pos].l&&tree[pos].r<=r) {        tree[pos].ok = 0;        return;    }    if(tree[pos].ok==0) {  //lay :push down         tree[pos*2].ok = 0;        tree[pos*2+1].ok = 0;    }    int mid=(tree[pos].l+tree[pos].r)>>1;    if(r<=mid)        update(pos*2,l,r);    else if(l>mid)        update(pos*2+1,l,r);    else  {        update(pos*2,l,mid);        update(pos*2+1,mid+1,r);    }    tree[pos].ok = tree[pos*2].ok + tree[pos*2+1].ok; //lay : push up}int query(int pos,int l,int r){   if(l<=tree[pos].l&&tree[pos].r<=r) {        return tree[pos].ok;   }   int mid=(tree[pos].l+tree[pos].r)>>1;    if(tree[pos].ok==0) {        tree[pos*2].ok = 0;        tree[pos*2+1].ok = 0;    }    if(r<=mid)       return query(pos*2,l,r);    else if(l>mid)       return query(pos*2+1,l,r);    else  {        return query(pos*2,l,mid)+ query(pos*2+1,mid+1,r);    }}int main(){  int N,Q;    cin>>N>>Q;    int index = 0;    for(int i=0;i<Q;i++) {        scanf("%d%d%d",&op[i][0],&op[i][1],&op[i][2]);        a[index++]=op[i][1];        a[index++]=op[i][2];    }    //两次离散化,防止有相邻的数据    sort(a,a+index);    int n=unique(a,a+index)-a;    int t = 0;    for(int i=1;i<n;i++){        if(a[i]-a[i-1]!=1){            a[n+t] =  a[i-1]+1;            t++;        }    }    sort(a,a+n+t);    n=unique(a,a+n+t)-a;    build(1,1,n);    for(int i=0;i<Q;i++) {        if(op[i][0]==1) {            update(1, lower_bound(a,a+n,op[i][1])-a+1 , lower_bound(a,a+n,op[i][2])-a+1 );        }else {            printf("%d\n",query(1, lower_bound(a,a+n,op[i][1])-a+1, lower_bound(a,a+n,op[i][2])-a+1 ));        }    } return 0;}
0 0
原创粉丝点击