【tyvj1473】校门外的树3

来源:互联网 发布:星达字段拼凑软件 编辑:程序博客网 时间:2024/05/01 04:26

tyvj1473

这道题可以用两个树状数组来做把每次更新的端点分别插入两个树状数组,在查询区间时,之前更新的区间会对当前查询区间产生影响的条件是
更新的末端点大于查询的始端点且更新的始端点小于等于查询的末端点,那么由于如果某次更新的始端点大于查询的末端点,那么这次更新的末端点也大于查询的末端点
因而我们所求的就是
已更新线段的末端点不小于查询的始端点的个数 - 已更新线段的始端点大于查询的末端点的个数

能用树状数组就不用线段树咯。。。毕竟10分钟A掉的题目就不麻烦写几种方法了

include<cstdio>using namespace std;const int maxn = 50000 + 10;int n, m, c1[maxn], c2[maxn];int lowbit(int x) { return x&-x; }void add1(int x){    while(x <= n){        c1[x]++;        x += lowbit(x);    }}void add2(int x){    while(x <= n){        c2[x]++;        x += lowbit(x);    }}int sum1(int x){    int cnt = 0;    while(x > 0){        cnt += c1[x];        x -= lowbit(x);    }    return cnt;}int sum2(int x){    int cnt = 0;    while(x > 0){        cnt += c2[x];        x -= lowbit(x);    }    return cnt;}int main(){    scanf("%d %d", &n, &m);    int k, l, r;    while(m--){        scanf("%d %d %d",&k, &l, &r);        if(k == 1){            add1(l);            add2(r);        }        else            printf("%d\n",( sum2(n)-sum2(l-1) ) - ( sum1(n)-sum1(r) ));    }    return 0;}

hzwer学长的线段树代码附上

#include<cstdio>#include<iostream>using namespace std;int n,m;struct data{    int l,r;    int left,right;}tr[200001];void build(int k,int s,int t){    tr[k].left=s;tr[k].right=t;    if(s==t)return;    int mid=(s+t)>>1;    build(k<<1,s,mid);    build(k<<1|1,mid+1,t);}void insertl(int k,int x,int y){    int l=tr[k].left,r=tr[k].right;    if(l==x&&y==r){tr[k].l++;return;}    int mid=(l+r)>>1;    if(y<=mid)insertl(k<<1,x,y);    else if(x>mid)insertl(k<<1|1,x,y);    else {        insertl(k<<1,x,mid);        insertl(k<<1|1,mid+1,y);    }}void insertr(int k,int x,int y){    int l=tr[k].left,r=tr[k].right;    if(l==x&&y==r){tr[k].r++;return;}    int mid=(l+r)>>1;    if(y<=mid)insertr(k<<1,x,y);    else if(x>mid)insertr(k<<1|1,x,y);    else {        insertr(k<<1,x,mid);        insertr(k<<1|1,mid+1,y);    }}int askl(int k,int x){    int l=tr[k].left,r=tr[k].right;    if(l==r)return tr[k].l;    int mid=(l+r)>>1;    if(x<=mid)return tr[k].l+askl(k<<1,x);    else return tr[k].l+askl(k<<1|1,x);}int askr(int k,int x){    int l=tr[k].left,r=tr[k].right;    if(l==r)return tr[k].r;    int mid=(l+r)>>1;    if(x<=mid)return tr[k].r+askr(k<<1,x);    else return tr[k].r+askr(k<<1|1,x);}int main(){    int total=0,ans;    scanf("%d%d",&n,&m);    build(1,0,n);    for(int i=1;i<=m;i++)       {           int t,a,b;           scanf("%d%d%d",&t,&a,&b);           if(t==1){              insertl(1,0,a-1);              insertr(1,b+1,n);              total++;              }           else           {              ans=askr(1,a)+askl(1,b);              printf("%d\n",total-ans);           }       }    return 0;}

hzwer学长博客

0 0
原创粉丝点击