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

操作形式:

A val pos:在pos位置上+val

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

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

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

 #include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define repu(i,a,b) for(int i=a;i<b;i++)
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
const int maxn = ;
const int M = ;
int h , w , n;
bool p[M];
int prime()
{
memset(p,false,sizeof(p));
p[] = p[] = true;
for(int i = ; i <= M; i += )
p[i] = true;
for(int i = ; i <= sqrt(M); i+=)
{
int k = i * ;
for(int j = i*i; j <= M; j += k)
p[j] = true;
}
}
struct Segment
{
int col[maxn<<];
int sum[maxn<<];
void init()
{
memset(col,,sizeof(col));
memset(sum,,sizeof(sum));
}
void PushUp(int rt)
{
sum[rt] = sum[rt<<] + sum[rt<<|];
}
void PushDown(int rt,int m)
{
if(col[rt] != -)///如果是0就进不去
{
col[rt<<] = col[rt<<|] = col[rt];
sum[rt<<] = (m - (m >> )) * col[rt];
sum[rt<<|] = (m >> ) * col[rt];
col[rt] = -;
}
}
void build(int l,int r,int rt)
{
col[rt] = -;
sum[rt] = ;
if (l == r) return ;
int m = (l + r) >> ;
build(lson);
build(rson);
PushUp(rt);
}
void Update(int p,int add,int l,int r,int rt)
{
if(l == r)
{
sum[rt] += add;
return ;
}
PushDown(rt , r - l + );
int m = (l + r) >> ;
if (p <= m) Update(p, add, lson);
else Update(p, add, rson);
PushUp(rt);
}
void update(int L,int R,int c,int l,int r,int rt)
{
if (L <= l && r <= R)
{
col[rt] = c;
///因为序列只有0,1;如果初始化为0的话,赋值有可能赋成0,pushdown就进不了,也就跟新不了数据了
sum[rt] = c * (r - l + );
return ;
}
PushDown(rt , r - l + );
int m = (l + r) >> ;
if (L <= m) update(L , R , c , lson);
if (R > m) update(L , R , c , rson);
PushUp(rt);
}
int query(int L,int R,int l,int r,int rt)
{
if (L <= l && r <= R)
{
return sum[rt];
}
PushDown(rt , r - l + );
int m = (l + r) >> ;
int ret = ;
if (L <= m) ret += query(L , R , lson);
if (m < R) ret += query(L , R , rson);
PushUp(rt);
return ret;
}
} Seg,seg;
int main()
{
int T , n , m, a , b , c;
prime();
scanf("%d",&T);
for (int cas = ; cas <= T ; cas ++)
{
Seg.init();
seg.init();
scanf("%d%d",&n,&m);
Seg.build( , n , );
seg.build( , n , );
repu(i,,n+)
{
scanf("%d",&a);
Seg.Update(i,a,,n,);
if(!p[a])///如果是质数才加1
seg.Update(i,,,n,);
}
char s[];
while(m--)
{
scanf("%s",s);
if(s[] == 'R')
{
scanf("%d%d%d",&a, &b, &c);
Seg.update(b , c , a , , n , );
if(!p[a])///如果是质数,更新成1
seg.update(b , c , , , n , );
else
seg.update(b , c , , , n , );
}
else if(s[] == 'A')
{
scanf("%d%d",&a,&b);///在b位置上加a,如果加的数字成了质数,也得更新另一棵树
int t = Seg.query(b,b,,n,);
Seg.Update(b,a,,n,);
if(!p[t+a] && p[t])///原本不是质数,变成了质数
seg.Update(b,,,n,);
else if(p[t+a] && !p[t])///原本是质数,变成了合数
seg.Update(b,-,,n,);
else if(p[t+a] && p[t]) ;
else if(!p[t+a] && !p[t]) ;
}
else
{
scanf("%d%d",&a,&b);
printf("%d\n",seg.query(a,b,,n,));
}
}
}
return ;
}

AC代码

ZOJ 3911 线段树的更多相关文章

  1. Prime Query (ZOJ 3911 线段树)

    Prime Query Time Limit: 1 Second Memory Limit: 196608 KB You are given a simple task. Given a sequen ...

  2. HDU 3911 线段树区间合并、异或取反操作

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=3911 线段树区间合并的题目,解释一下代码中声明数组的作用: m1是区间内连续1的最长长度,m0是区间内连续 ...

  3. ZOJ 3279-Ants(线段树)

    传送门:zoj 3279 Ants Ants Time Limit: 2 Seconds      Memory Limit: 32768 KB echo is a curious and cleve ...

  4. zoj 3888 线段树 ***

    卡n^2,用线段树降到nlogn 记录每个点上所覆盖线段的次小值,保证能有两条路径能走 #include<cstdio> #include<iostream> #include ...

  5. F - Count the Colors ZOJ - 1610 线段树染色(染区间映射)

    题意:给一段0-8000的线段染色 问最后 颜色x 有几段 题解:标准线段树  但是没有push_up  最后查询是单点按顺序查询每一个点 考虑过使用区间来维护不同的线段有多少种各色的线段  思路是 ...

  6. HDU 3911 线段树区间合并

    北京赛区快了,准备袭击数据结构和图论.倒计时 18天,线段树区间合并.维护一个最长连续.. 题意:给一个01串,以下有一些操作,问区间最长的连续的1的个数 思路:非常裸的线段树区间合并 #includ ...

  7. HDU 1199 &amp;&amp; ZOJ 2301 线段树离散化

    一段长度未知的线段.一种操作:a b c ,表示区间[a,b]涂为颜色C,w代表白色,b代表黑色,问终于的最长连续白色段,输出起始位置和终止位置 离散化处理.和寻常的离散化不同,须要把点化成线段.左闭 ...

  8. zoj 2706 线段树

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1706 trick:关于正数和负数的整除问题,正数整除是自动向下取整的 ...

  9. ZOJ 3299 线段树 离散化

    本来是个很简单的题目,难住我的主要是这么几点 1.它所有的点都是坐标,不是实际的砖块,1,3指的是1-2 2-3的砖块...后来就是用1 代表1-2 ,2代表2-3.....,这样的话,每次读入的数据 ...

随机推荐

  1. 设计模式学习笔记-Adapter模式

    Adapter模式,就是适配器模式,使两个原本没有关联的类结合一起使用. 平时我们会经常碰到这样的情况,有了两个现成的类,它们之间没有什么联系,但是我们现在既想用其中一个类的方法,同时也想用另外一个类 ...

  2. 基于事件的异步模式(EAP)

    什么是EAP异步编程模式 EAP基于事件的异步模式是.net 2.0提出来的,实现了基于事件的异步模式的类将具有一个或者多个以Async为后缀的方法和对应的Completed事件,并且这些类都支持异步 ...

  3. SCSS

    CSS 预处理器定义了一种新的语言,其基本思想是,用一种专门的编程语言,为 CSS 增加了一些编程的特性,将 CSS 作为目标生成文件,然后开发者就只要使用这种语言进行编码工作. 通俗的说,“CSS ...

  4. adapter用法

    Android之Adapter用法总结 1.概念 Adapter是连接后端数据和前端显示的适配器接口,是数据和UI(View)之间一个重要的纽带.在常见的View(ListView,GridView) ...

  5. Codeforces Round #380 (Div. 1, Rated, Based on Technocup 2017 - Elimination Round 2)

    http://codeforces.com/contest/737 A: 题目大意: 有n辆车,每辆车有一个价钱ci和油箱容量vi.在x轴上,起点为0,终点为s,中途有k个加油站,坐标分别是pi,到每 ...

  6. Android中的数据保存

    形式 Android的数据保存分为3种形式:file, SharedPreference, Database 文件 主要思想就是通过Context类中提供的openFileInput和openFile ...

  7. Emacs 常用快捷键

    关闭欢迎界面:Q 保存:c-x c-s 退出:c-x c-c 暂时退出:c-z       屏幕滚动 移动到下一屏:c-v 移动到上一屏:m-v 将光标所在行置中:c-L       光标移动 上一行 ...

  8. 【转】MySQL中varchar最大长度是多少?

    一. varchar存储规则: 4.0版本以下,varchar(20),指的是20字节,如果存放UTF8汉字时,只能存6个(每个汉字3字节) 5.0版本以上,varchar(20),指的是20字符,无 ...

  9. ado.net中,数据的批量处理

    //btBigImport按钮点击事件 private void btBigImport_Click(object sender, RoutedEventArgs e)        { //连接字符 ...

  10. 关于粒子发射(CAEmitterLayer)

    技术是条长而远的路,只有不断学习丰富自己的技能才能让自己行走在路上! CAEmitterCell CAEmitterCell: CAEmitterCell是粒子发射系统里的粒子,用CAEmitterC ...