您的位置:首页 > 其它

【tyvj1473】校门外的树3

2016-03-29 18:46 260 查看
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", &
4000
amp;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学长博客
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: