区间更新 zoj3911

哎,没什么坑点,一个简单的区间更新题,但是改了好几天没改对,最终还是过了~~发个纪念下

泪奔。。。

#include<cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#define N 100010
#define MAXN 10000010
using namespace std;
struct dd
{
int cnt;//这个区间内素数的个数
int l,r;
int val;//存的是素数
int flag;//区间更新的标记
}tree[N<<2];
int isp[MAXN];
void inint()//素数打表
{
memset(isp,0,sizeof(isp));
isp[0]=isp[1]=1;
for(int i=2;i<MAXN;i++)
{
if(!isp[i])
{
if(i>MAXN/i)
continue;
for(int j=i*i;j<MAXN;j+=i)
isp[j]=1;
}
}
}
void push_up(int k)//更新父亲节点
{
tree[k].cnt=tree[k<<1].cnt+tree[k<<1|1].cnt;
}
void push_down(int k)//区间更新
{
if(tree[k].flag)
{
tree[k<<1].flag=tree[k<<1|1].flag=tree[k].flag;
tree[k<<1].val=tree[k<<1|1].val=tree[k].val;
tree[k<<1].cnt=(isp[tree[k].flag])?0:tree[k<<1].r-tree[k<<1].l+1;
tree[k<<1|1].cnt=(isp[tree[k].flag])?0:tree[k<<1|1].r-tree[k<<1|1].l+1;
tree[k].flag=0;
}
}
void build(int l,int r,int k)//建树
{
tree[k].l=l;
tree[k].r=r;
tree[k].cnt=0;
tree[k].flag=0;
tree[k].val=0;
if(l==r)
{
int val;
scanf("%d",&val);
tree[k].val=val;
if(!isp[val])
tree[k].cnt=1;
return;
}
int mid=(l+r)/2;
build(l,mid,k<<1);
build(mid+1,r,k<<1|1);
push_up(k);
}
void update1(int val,int pos,int k)//更新一个节点
{
if(tree[k].l==tree[k].r&&tree[k].l==pos)
{
tree[k].val+=val;
if(!isp[tree[k].val])
tree[k].cnt=1;
else
tree[k].cnt=0;
return;
}
push_down(k);//这里的push_down竟然没加!!!泪奔的是,还是自己删掉的,好久才发现
int mid=(tree[k].l+tree[k].r)/2;
if(pos<=mid)
update1(val,pos,k<<1);
else
update1(val,pos,k<<1|1);
push_up(k);
}
void update2(int val,int l,int r,int k)//更新区间
{
if(tree[k].l==l&&tree[k].r==r)
{
tree[k].cnt=(isp[val])?0:tree[k].r-tree[k].l+1;//开始的时候这里的cnt值也忘了改
tree[k].val=val;
tree[k].flag=val;
return;
}
push_down(k);
int mid=(tree[k].l+tree[k].r)/2;
if(r<=mid) update2(val,l,r,k<<1);
else if(l>mid) update2(val,l,r,k<<1|1);
else
{
update2(val,l,mid,k<<1);
update2(val,mid+1,r,k<<1|1);
}
push_up(k);
}

int query(int k,int l,int r)//询问区间内的元素数
{
int sum=0;
if(tree[k].l==l&&tree[k].r==r)
{
return tree[k].cnt;
}
push_down(k);
int mid=(tree[k].l+tree[k].r)/2;
if(mid>=r)
sum+=query(k<<1,l,r);
else if(l>mid)
sum+=query(k<<1|1,l,r);
else
{
sum+=query(k<<1,l,mid);
sum+=query(k<<1|1,mid+1,r);
}
push_up(k);
return sum;
}
int main()
{
int t,n,q;
char op[5];
//printf("%d ",2|1);
inint();
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&q);
build(1,n,1);
while(q--)
{
scanf("%s",op);
if(op[0]=='A')//pos这个点的元素加val
{
int val,pos;
scanf("%d%d",&val,&pos);
update1(val,pos,1);
}
else if(op[0]=='R')//l,r区间内的元素都改为val
{
int val,l,r;
scanf("%d%d%d",&val,&l,&r);
update2(val,l,r,1);
}
else if(op[0]=='Q')//询问区间内的元素数
{
int l,r;
scanf("%d%d",&l,&r);
int sum=query(1,l,r);
printf("%d ",sum);
}
}
}
return 0;
}

原文地址:https://www.cnblogs.com/dj3839/p/4890009.html