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);
            }
        }
    }
}
View Code

猜你喜欢

转载自www.cnblogs.com/ctyakwf/p/12631003.html