ZOJ3911 Prime Query(线段树)
本题比较简单,就是线段树的几个基本操作,而素数,我们自然想到用素数筛筛一下后直接判定即可
这里有几个小坑点,在单点更新的时候也需要pushdown,因为区间更新可能会影响到最后节点的值
另外按照我的写法,我把lazy和数值分开表示,所以在pushdown的时候要特判是否到了叶子,如果到了,num也需要修改,不然只需要修改lazy即可
更好的写法是,直接把数值用lazy表示
#include<iostream> #include<cstring> #include<cstdio> #include<map> #include<algorithm> #include<queue> #include<set> #define ull unsigned long long using namespace std; typedef long long ll; typedef pair<int,int> pll; const int N=1e6+10; const int mod=1e7+10; int a[N]; int primes[mod],st[mod]; int cnt; struct node{ int l,r; int cnt; int lazy; int num; }tr[N<<2]; void init(int n){ st[0]=st[1]=1; for(int i=2; i<=10000001; ++i) if(!st[i]){ for(int j=i*2; j<=10000001; j+=i) st[j]=1; } } void pushup(int u){ tr[u].cnt=tr[u<<1].cnt+tr[u<<1|1].cnt; } void build(int u,int l,int r){ if(l==r){ tr[u]=node{l,l,0,a[l],a[l]}; if(!st[a[l]]) tr[u].cnt=1; } else{ tr[u]=node{l,r}; int mid=l+r>>1; build(u<<1,l,mid); build(u<<1|1,mid+1,r); pushup(u); } } void pushdown(int u){ if(tr[u].lazy){ tr[u<<1].lazy=tr[u<<1|1].lazy=tr[u].lazy; if(tr[u<<1].l==tr[u<<1].r){ tr[u<<1].num=tr[u].lazy; } if(tr[u<<1|1].l==tr[u<<1].r){ tr[u<<1|1].num=tr[u].lazy; } tr[u<<1].cnt=(st[tr[u].lazy]==0)?tr[u<<1].r-tr[u<<1].l+1:0; tr[u<<1|1].cnt=(st[tr[u].lazy]==0)?tr[u<<1|1].r-tr[u<<1|1].l+1:0; tr[u].lazy=0; } } void update(int u,int l,int x){ if(tr[u].l==tr[u].r){ tr[u].num+=x; if(!st[tr[u].num]) tr[u].cnt=1; else tr[u].cnt=0; return ; } pushdown(u); int mid=tr[u].l+tr[u].r>>1; if(l<=mid) update(u<<1,l,x); else update(u<<1|1,l,x); pushup(u); } void modify(int u,int l,int r,int x){ if(tr[u].l>=l&&tr[u].r<=r){ tr[u].lazy=x; if(!st[x]){ tr[u].cnt=tr[u].r-tr[u].l+1; } else{ tr[u].cnt=0; } return ; } pushdown(u); int mid=tr[u].l+tr[u].r>>1; if(l<=mid) modify(u<<1,l,r,x); if(r>mid) modify(u<<1|1,l,r,x); pushup(u); } int query(int u,int l,int r){ if(tr[u].l>=l&&tr[u].r<=r){ return tr[u].cnt; } pushdown(u); int mid=tr[u].l+tr[u].r>>1; int ans=0; if(l<=mid) ans+=query(u<<1,l,r); if(r>mid) ans+=query(u<<1|1,l,r); pushup(u); return ans; } int main(){ int t; cin>>t; init(mod); int i; while(t--){ int n,q; cin>>n>>q; int i; for(i=1;i<=n;i++){ scanf("%d",&a[i]); } build(1,1,n); while(q--){ int l,r; string s; cin>>s; int v; if(s=="A"){ scanf("%d%d",&v,&l); update(1,l,v); } else if(s=="R"){ scanf("%d%d%d",&v,&l,&r); modify(1,l,r,v); } else{ scanf("%d%d",&l,&r); int num=query(1,l,r); printf("%d\n",num); } } } }
没有人不辛苦,只有人不喊疼