• ZOJ 3911 线段树


    题意:有N个数字,M个操作,然后回答每个Q开头的询问

    操作形式:

    A val pos:在pos位置上+val

    Q l r:询问l~r之间有多少个质数

    R val l r:把l~r之间的数字替换成val

    分析:建成两棵树,一棵更新 原数列,一棵更新 质数序列(只有0,1)

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <cmath>
      4 #include <algorithm>
      5 using namespace std;
      6 #define repu(i,a,b) for(int i=a;i<b;i++)
      7 #define lson l , m , rt << 1
      8 #define rson m + 1 , r , rt << 1 | 1
      9 const int maxn = 111111;
     10 const int M = 10000010;
     11 int h , w , n;
     12 bool p[M];
     13 int prime()
     14 {
     15     memset(p,false,sizeof(p));
     16     p[0] = p[1] = true;
     17     for(int i = 4; i <= M; i += 2)
     18         p[i] = true;
     19     for(int i = 3; i <= sqrt(M); i+=2)
     20     {
     21         int k = i * 2;
     22         for(int j = i*i; j <= M; j += k)
     23             p[j] = true;
     24     }
     25 }
     26 struct Segment
     27 {
     28     int col[maxn<<2];
     29     int sum[maxn<<2];
     30     void init()
     31     {
     32         memset(col,0,sizeof(col));
     33         memset(sum,0,sizeof(sum));
     34     }
     35     void PushUp(int rt)
     36     {
     37         sum[rt] = sum[rt<<1] + sum[rt<<1|1];
     38     }
     39     void PushDown(int rt,int m)
     40     {
     41         if(col[rt] != -1)///如果是0就进不去
     42         {
     43             col[rt<<1] = col[rt<<1|1] = col[rt];
     44             sum[rt<<1] = (m - (m >> 1)) * col[rt];
     45             sum[rt<<1|1] = (m >> 1) * col[rt];
     46             col[rt] = -1;
     47         }
     48     }
     49     void build(int l,int r,int rt)
     50     {
     51         col[rt] = -1;
     52         sum[rt] = 0;
     53         if (l == r) return ;
     54         int m = (l + r) >> 1;
     55         build(lson);
     56         build(rson);
     57         PushUp(rt);
     58     }
     59     void Update(int p,int add,int l,int r,int rt)
     60     {
     61         if(l == r)
     62         {
     63             sum[rt] += add;
     64             return ;
     65         }
     66         PushDown(rt , r - l + 1);
     67         int m = (l + r) >> 1;
     68         if (p <= m) Update(p, add, lson);
     69         else Update(p, add, rson);
     70         PushUp(rt);
     71     }
     72     void update(int L,int R,int c,int l,int r,int rt)
     73     {
     74         if (L <= l && r <= R)
     75         {
     76             col[rt] = c;
     77             ///因为序列只有0,1;如果初始化为0的话,赋值有可能赋成0,pushdown就进不了,也就跟新不了数据了
     78             sum[rt] = c * (r - l + 1);
     79             return ;
     80         }
     81         PushDown(rt , r - l + 1);
     82         int m = (l + r) >> 1;
     83         if (L <= m) update(L , R , c , lson);
     84         if (R > m) update(L , R , c , rson);
     85         PushUp(rt);
     86     }
     87     int query(int L,int R,int l,int r,int rt)
     88     {
     89         if (L <= l && r <= R)
     90         {
     91             return sum[rt];
     92         }
     93         PushDown(rt , r - l + 1);
     94         int m = (l + r) >> 1;
     95         int ret = 0;
     96         if (L <= m) ret += query(L , R , lson);
     97         if (m < R) ret += query(L , R , rson);
     98         PushUp(rt);
     99         return ret;
    100     }
    101 } Seg,seg;
    102 int main()
    103 {
    104     int T , n , m, a , b , c;
    105     prime();
    106     scanf("%d",&T);
    107     for (int cas = 1 ; cas <= T ; cas ++)
    108     {
    109         Seg.init();
    110         seg.init();
    111         scanf("%d%d",&n,&m);
    112         Seg.build(1 , n , 1);
    113         seg.build(1 , n , 1);
    114         repu(i,1,n+1)
    115         {
    116             scanf("%d",&a);
    117             Seg.Update(i,a,1,n,1);
    118             if(!p[a])///如果是质数才加1
    119                 seg.Update(i,1,1,n,1);
    120         }
    121         char s[4];
    122         while(m--)
    123         {
    124             scanf("%s",s);
    125             if(s[0] == 'R')
    126             {
    127                 scanf("%d%d%d",&a, &b, &c);
    128                 Seg.update(b , c , a , 1 , n , 1);
    129                 if(!p[a])///如果是质数,更新成1
    130                     seg.update(b , c , 1 , 1 , n , 1);
    131                 else
    132                     seg.update(b , c , 0 , 1 , n , 1);
    133             }
    134             else if(s[0] == 'A')
    135             {
    136                 scanf("%d%d",&a,&b);///在b位置上加a,如果加的数字成了质数,也得更新另一棵树
    137                 int t = Seg.query(b,b,1,n,1);
    138                 Seg.Update(b,a,1,n,1);
    139                 if(!p[t+a] && p[t])///原本不是质数,变成了质数
    140                     seg.Update(b,1,1,n,1);
    141                 else if(p[t+a] && !p[t])///原本是质数,变成了合数
    142                     seg.Update(b,-1,1,n,1);
    143                 else if(p[t+a] && p[t]) ;
    144                 else if(!p[t+a] && !p[t]) ;
    145             }
    146             else
    147             {
    148                 scanf("%d%d",&a,&b);
    149                 printf("%d
    ",seg.query(a,b,1,n,1));
    150             }
    151         }
    152     }
    153     return 0;
    154 }
    AC代码
  • 相关阅读:
    C面试复习笔记
    Java面试复习笔记
    Jdk1.6 HTTPS访问问题解决办法
    百度地图轨迹回放,自定义路书,边走边画线
    简单的代码生成小工具(支持模板)
    card布局解决复杂操作的布局问题
    tabpanel如何隐藏页签表头以及基本用法总结
    ExtJS4.2下将表单元素放在菜单时不能进行拷贝的问题解决办法
    照片元数据信息以及在照片中写入gps信息
    带名称空间的xml数据查询
  • 原文地址:https://www.cnblogs.com/ACMERY/p/4875496.html
Copyright © 2020-2023  润新知