- 校门外的树
- 2016-02-18 11:56:05 @
#include<cstdio>
#include<iostream>
#define MAXN 50005
using namespace std;
//use of main
int n,m;
//use of two
int two[30]={0};
void pre_two()
{
int num=0;
two[0]=1;
while(two[num]<=m)
{two[++num]=two[num-1]*2;}
}
int cnt(int num)
{
int temp=0;
while(num>0)
{
if(num%2==1)
temp++;
num/=2;
}
return temp;
}
//use of tree
struct tree
{
int v,add;
tree()
{v=add=0;}
}use[MAXN*4];
inline int lc(int x){return x<<1;}
inline int rc(int x){return x<<1|1;}
void build(int x,int l,int r)
{
if(l==r)return ;
int mid=(l+r)>>1;
build(lc(x),l,mid);
build(rc(x),mid+1,r);
}
//lazy
inline void down(int x)
{
if(use[x].add!=0)
{
int l=lc(x),r=rc(x);
use[l].v|=use[x].add;
use[r].v|=use[x].add;
use[l].add|=use[x].add;
use[r].add|=use[x].add;
use[x].add=0;
}
}
inline void up(int x)
{
use[x].v=(use[lc(x)].v|use[rc(x)].v);
}
void updata(int x,int l,int r,int op,int ed,int v)
{
if(op<=l&&r<=ed)
{
use[x].add|=v;
use[x].v|=v;
return ;
}
down(x);
int mid=(l+r)>>1;
if(op<=mid)
updata(lc(x),l,mid,op,ed,v);
if(ed>mid)
updata(rc(x),mid+1,r,op,ed,v);
up(x);
}
int query(int x,int l,int r,int op,int ed)
{
if(op<=l&&r<=ed)
return use[x].v;
down(x);
int mid=(l+r)>>1;
int a=0,b=0;
if(op<=mid)
a=query(lc(x),l,mid,op,ed);
if(ed>mid)
b=query(rc(x),mid+1,r,op,ed);
return (a|b);
}
int main()
{
scanf("%d%d",&n,&m);
pre_two();
build(1,1,n);
int k,t1,t2;
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&k,&t1,&t2);
if(k==1)
{
updata(1,1,n,t1,t2,two[i]);
}
else if(k==2)
{
printf("%d\n",cnt(query(1,1,n,t1,t2)));
}
}
//while(1);
return 0;
}
样例OK ,第一条过,,,其余RE。。。为什么?
1 条评论
-
hfz LV 8 @ 2016-03-09 20:08:55
这题需要传递么??
- 1