luogu P2184 贪婪大陆

luogu P2184 贪婪大陆_第1张图片

anayisis

线段树
对于每一个询问,若我们查询到这个询问的右界的左边[0,R]有x个地雷区间的开头,左界的左边[0,L-1]有y个地雷区间的结束,由于一个区间的结尾必定对应一个在其前面的开头,故区间[L,R]中颜色的个数就等于x-y,类似于差分的思想

code

#include
using namespace std;
#define loop(i,start,end) for(register int i=start;i<=end;++i)
#define anti_loop(i,start,end) for(register int i=start;i>=end;--i)
#define clean(arry,num) memset(arry,num,sizeof(arry))
#define max(a,b) ((a>b)?a:b)
#define min(a,b) ((a
#define ll long long
template<typename T>void read(T &x){
    x=0;char r=getchar();T neg=1;
    while(r>'9'||r<'0'){if(r=='-')neg=-1;r=getchar();}
    while(r>='0'&&r<='9'){x=(x<<1)+(x<<3)+r-'0';r=getchar();}
    x*=neg;
}
const int maxn=1e5+10;
int sum_s[maxn<<2],sum_e[maxn<<2];
int n,m;
inline void buildtree(){clean(sum_s,0);clean(sum_e,0);}
void update(int pos,int nl,int nr,int rt,int LOR/*左还是右*/){
    if(nl==nr&&nr==pos){
        if(LOR==0)++sum_s[rt];
        else ++sum_e[rt];
        return;
    }
    int mid=(nl+nr)>>1;
    if(mid>=pos)update(pos,nl,mid,rt<<1,LOR);
    else if(mid<pos)update(pos,mid+1,nr,rt<<1|1,LOR);
    if(LOR==0)sum_s[rt]=sum_s[rt<<1]+sum_s[rt<<1|1];
    else sum_e[rt]=sum_e[rt<<1]+sum_e[rt<<1|1];
}
int query(int l,int r,int nl,int nr,int rt,int LOR){
    if(l>r)return 0;
    if(l<=nl&&nr<=r){
        if(LOR==0)return sum_s[rt];
        else return sum_e[rt];
    }
    int mid=(nl+nr)>>1;
    int _sum=0;
    if(mid>=l)_sum+=query(l,r,nl,mid,rt<<1,LOR);
    if(mid<r)_sum+=query(l,r,mid+1,nr,rt<<1|1,LOR);
    return _sum;
}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("datain.txt","r",stdin);
    #endif // ONLINE_JUDGE
    read(n),read(m);    
    #ifndef ONLINE_JUDGE
    freopen("con","r",stdin);
    #endif // ONLINE_JUDGE
    loop(i,1,m){
        int Q,L,R;
        read(Q),read(L),read(R);
        if(Q==1){
            update(L,1,n,1,0);
            update(R,1,n,1,1);
        }
        else if(Q==2){
            printf("%d\n",query(1,R,1,n,1,0)-query(1,L-1,1,n,1,1));
        }
    }
    return 0;
}

你可能感兴趣的:(数据结构)