zoukankan      html  css  js  c++  java
  • 区间更新 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;
    }

  • 相关阅读:
    UVA
    hdu 5584 LCM Walk
    UVA 10791 -唯一分解定理的应用
    UVA-10375 唯一分解定理
    UVA-11582
    UVA
    大连CCPC D
    java切割~~百万 十万 万 千 百 十 个 角 分
    js文字颜色闪烁
    日期比较大小给小的月份加1
  • 原文地址:https://www.cnblogs.com/dj3839/p/4890009.html
Copyright © 2011-2022 走看看