zoukankan      html  css  js  c++  java
  • SPOJ CNTPRIME 13015 Counting Primes (水题,区间更新,求区间的素数个数)

     题目连接:http://www.spoj.com/problems/CNTPRIME/

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #define lson rt<<1,L,mid
    #define rson rt<<1|1,mid+1,R
    /*
    水题
    题意:给出n个初始值,给出两种操作
          0 x y v:将[x,y]的数改成v
          1 x y :查询[x,y]区间有多少个素数(相同的数,有几个算几个,即有两个3,那么个数为2)
    */
    using namespace std;
    const int maxn=1000005;
    int t,n,q;
    bool isprime[maxn];
    
    struct Node{
        int sum;  //统计该区间的素数个数
        int lazy;
        int len;
    }tree[maxn<<2];
    
    //素数筛选法
    void init(){
        memset(isprime,true,sizeof(isprime));
        for(int i=2;i<maxn;i++){
            if(isprime[i]){
                for(int j=i*2;j<maxn;j+=i){
                    isprime[j]=false;
                }
            }
        }
    }
    void pushUp(int rt){
        tree[rt].sum=tree[rt<<1].sum+tree[rt<<1|1].sum;
    }
    void pushDown(int rt){
        if(tree[rt].lazy!=-1){
            tree[rt<<1].lazy=tree[rt<<1|1].lazy=tree[rt].lazy;
            tree[rt<<1].sum=tree[rt].lazy?tree[rt<<1].len:0;
            tree[rt<<1|1].sum=tree[rt].lazy?tree[rt<<1|1].len:0;
            tree[rt].lazy=-1;
        }
    }
    void build(int rt,int L,int R){
        tree[rt].lazy=-1;
        tree[rt].len=R-L+1;
        if(L==R){
            int v;
            scanf("%d",&v);
            if(isprime[v])
                tree[rt].sum=1;
            else
                tree[rt].sum=0;
            return;
        }
        int mid=(L+R)>>1;
        build(lson);
        build(rson);
        pushUp(rt);
    }
    void update(int rt,int L,int R,int l,int r,int v){
        if(l<=L&&R<=r){
            if(isprime[v]){
                tree[rt].sum=R-L+1;
                tree[rt].lazy=1;
            }
            else{
                tree[rt].sum=0;
                tree[rt].lazy=0;
            }
            return;
        }
        pushDown(rt);
        int mid=(L+R)>>1;
        if(l<=mid)
            update(lson,l,r,v);
        if(r>mid)
            update(rson,l,r,v);
        pushUp(rt);
    }
    int query(int rt,int L,int R,int l,int r){
        if(l<=L&&R<=r){
            return tree[rt].sum;
        }
        int mid=(R+L)>>1;
        int ret=0;
        pushDown(rt);
        if(l<=mid)
            ret+=query(lson,l,r);
        if(r>mid)
            ret+=query(rson,l,r);
        return ret;
    }
    int main()
    {
        init();
        int op,x,y,v;
        scanf("%d",&t);
        for(int i=1;i<=t;i++){
            printf("Case %d:
    ",i);
            scanf("%d%d",&n,&q);
            build(1,1,n);
            for(int j=1;j<=q;j++){
                scanf("%d",&op);
                if(op==0){
                    scanf("%d%d%d",&x,&y,&v);
                    update(1,1,n,x,y,v);
                }
                else{
                    scanf("%d%d",&x,&y);
                    printf("%d
    ",query(1,1,n,x,y));
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    camke 参数
    17.计算1-100之和+1-50的平方和+1-10的倒数
    16.求Sn=a+aa+aaa+aaaa.......之值
    15.计算1!+2!+3!+.....20!=?
    14.输出所有的“水仙花”
    13.企业发放的奖金根据利润提成
    12.输入一个成绩计算其A,B,C,D,E等级
    11.键盘输入小于1000的整数
    10.求方程的根
    2019考研历程回顾
  • 原文地址:https://www.cnblogs.com/chenxiwenruo/p/3420701.html
Copyright © 2011-2022 走看看