Prime Query


Time Limit: 1 Second      Memory Limit: 196608 KB

You are given a simple task. Given a sequence A[i] with N numbers. You have to perform Q operations on the given sequence.

Here are the operations:

  • A v l, add the value v to element with index l.(1<=V<=1000)
  • R a l r, replace all the elements of sequence with index i(l<=i<= r) with a(1<=a<=10^6) .
  • Q l r, print the number of elements with index i(l<=i<=r) and A[i] is a prime number

Note that no number in sequence ever will exceed 10^7.

Input

The first line is a signer integer T which is the number of test cases.

For each test case, The first line contains two numbers N and Q (1 <= N, Q <= 100000) - the number of elements in sequence and the number of queries.

The second line contains N numbers - the elements of the sequence.

In next Q lines, each line contains an operation to be performed on the sequence.

Output

For each test case and each query,print the answer in one line.

Sample Input

1
5 10
1 2 3 4 5
A 3 1
Q 1 3
R 5 2 4
A 1 1
Q 1 1
Q 1 2
Q 1 4
A 3 5
Q 5 5
Q 1 5

Sample Output

2
1
2
4
0
4

题目大意:三种类型的操作。A操作单点更新,给某位置增加值v,R操作区间更新,整个区间都更新为值v,Q操作区间查询,查询区间内的素数个数。

解题思路:用线段树维护三个值,一个lazy标记,一个val表示点的值,一个pnum表示素数的个数。在单点查询的时候,用一个PushDown操作将lazy标记下放,同时将值下发。最后还要用PushUp操作在回溯的时候更新值。对于区间查询来说,在查询的时候将lazy下放。关键要写好PushDown和PushUp这两个操作。(今天比较坑,自己建树的时候,没有上推,QAQ)。

#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<iostream>
using namespace std;
#define mid (L+R)/2
#define lson rt*2,L,mid
#define rson rt*2+1,mid+1,R
const int maxn=1e5+200;
const int maxv=1e7+200;
struct SegTree{
int val,pnum,lazy;
}segtrees[maxn*4];
int prime[maxv],pprime[maxv];
void getprime(){
int num_prime=0;
prime[0]=prime[1]=1;
for(int i=2;i<maxv;i++){
if(!prime[i])
pprime[num_prime++]=i;
for(int j=0;j<num_prime && i*pprime[j]<maxv;j++){
prime[i*pprime[j]]=1;//合数标为1,同时,prime[j]是合数i*prime[j]的最小素因子
if(!(i%pprime[j]))//即比一个合数大的质数和该合数的乘积可用一个更大的合数和比其小的质数相乘得到
break;
}
}
}
void PushUp(int rt){
segtrees[rt].pnum = segtrees[rt*2].pnum + segtrees[rt*2+1].pnum; //
}
void build(int rt,int L,int R){
segtrees[rt].val=0;
segtrees[rt].lazy=0;
segtrees[rt].pnum=0;
if(L==R){
int &v=segtrees[rt].val;
scanf("%d",&v);
if(prime[v]){
segtrees[rt].pnum=0;
}else{
segtrees[rt].pnum=1;
}
return ;
}
build(lson);
build(rson);
PushUp(rt);
} void PushDown(int rt,int L,int R){
if(segtrees[rt].lazy==1){ segtrees[rt].lazy=0;
segtrees[rt*2].lazy=1;
segtrees[rt*2+1].lazy=1; segtrees[rt*2].val=segtrees[rt].val;
segtrees[rt*2+1].val=segtrees[rt].val;
segtrees[rt].val=0;
}
}
void add(int rt,int L,int R,int pos,int _val){
if(L==R){
int &v=segtrees[rt].val;
v+=_val;
if(prime[v]){
segtrees[rt].pnum=0;
}else{
segtrees[rt].pnum=1;
}
return ;
}
PushDown(rt,L,R);
if(pos<=mid){
add(lson,pos,_val);
}else{
add(rson,pos,_val);
}
PushUp(rt);
}
void repla(int rt,int L,int R,int l_ran,int r_ran,int _val){
if(l_ran<=L&&R<=r_ran){
segtrees[rt].lazy=1;
segtrees[rt].val=_val;
int &v=segtrees[rt].val;
if(prime[v]){
segtrees[rt].pnum=0;
}else{
segtrees[rt].pnum=R-L+1;
}
return ;
}
PushDown(rt,L,R);
if(l_ran<=mid){
repla(lson,l_ran,r_ran,_val);
} if(r_ran>mid){
repla(rson,l_ran,r_ran,_val);
}
PushUp(rt);
}
int query(int rt,int L,int R,int l_ran,int r_ran){
if(l_ran<=L&&R<=r_ran){
return segtrees[rt].pnum;
}
PushDown(rt,L,R);
int ret=0;
if(l_ran<=mid){
ret+=query(lson,l_ran,r_ran);
}
if(r_ran>mid){
ret+=query(rson,l_ran,r_ran);
}
return ret;
}
int main(){
int T,n,m;
char opr[10];
getprime();
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
build(1,1,n);
int a,b,c;
for(int i=1;i<=m;i++){
scanf("%s",opr);
if(opr[0]=='A'){
scanf("%d %d",&a,&b);
add(1,1,n,b,a);
}else if(opr[0]=='R'){
scanf("%d %d %d",&a,&b,&c);
repla(1,1,n,b,c,a);
}else{
scanf("%d %d",&a,&b);
int ans=query(1,1,n,a,b);
printf("%d\n",ans);
}
}
}
return 0;
}

  

ZOJ 5638——Prime Query——————【线段树区间更新,区间查询,单点更新】的更多相关文章

  1. HUD.2795 Billboard ( 线段树 区间最值 单点更新 单点查询 建树技巧)

    HUD.2795 Billboard ( 线段树 区间最值 单点更新 单点查询 建树技巧) 题意分析 题目大意:一个h*w的公告牌,要在其上贴公告. 输入的是1*wi的w值,这些是公告的尺寸. 贴公告 ...

  2. 51nod1287(二分/线段树区间最值&单点更新)

    题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1287 题意:中文题诶- 解法1:b[i] 存储 max(a[0 ...

  3. hdoj1754 I Hate It【线段树区间最大值维护+单点更新】

    I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

  4. 【线段树区间最值单点更新模板】BNUOJ 52965 E Excellent Engineers

    http://acm.bnu.edu.cn/v3/external/gym/101512.pdf #include<bits/stdc++.h> using namespace std; ...

  5. POJ3468(线段树区间求和+区间查询)

    https://vjudge.net/contest/66989#problem/C You have N integers, A1, A2, ... , AN. You need to deal w ...

  6. 143 - ZOJ Monthly, October 2015 I Prime Query 线段树

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

  7. query 线段树 + 区间排序

    https://nanti.jisuanke.com/t/41391 这个题目没有很难想,比较暴力,但是要会算复杂度,不会算复杂度,就会觉得自己的算法会超时,实际上不会. 这个题目就是直接暴力求出每一 ...

  8. SPOJ GSS2 - Can you answer these queries II(线段树 区间修改+区间查询)(后缀和)

    GSS2 - Can you answer these queries II #tree Being a completist and a simplist, kid Yang Zhe cannot ...

  9. poj3667(线段树区间合并&区间查询)

    题目链接: http://poj.org/problem?id=3667 题意:第一行输入 n, m表示有 n 间房间(连成一排的), 接下来有 m 行输入, 对于接下来的 m 行输入: 1 x : ...

随机推荐

  1. 如何更新node和npm版本

    更新npm --->  npm undate -g 更新node --->  npm install -g -n n latest

  2. Zeppelin的入门使用系列之创建新的Notebook(一)

    不多说,直接上干货! 前期博客 hadoop-2.6.0.tar.gz + spark-1.6.1-bin-hadoop2.6.tgz + zeppelin-0.5.6-incubating-bin- ...

  3. linux 安装输入法

    简述 Ubuntu16.04安装完后,和12.04以及14.04都不一样,并没有中文输入功能.于是搜索一些安装中文输入法的方法. 开始安装了ibus pinyin输入法,但是系统重启之后发现有些时候不 ...

  4. 项目一:第七天 CRM 和bos系统实现定区关联客户,关联快递员. 通过CXF框架实现

    定区关联客户 需求:为了快递方便客户下订单(发快递),派快递员上门取件.  所以说需要让定区关联客户(知道客户属于哪个定区),定区跟快递员关系:多对多.知道让哪个快递员上门取件. 将CRM系统中,客户 ...

  5. servlet与filter的加载顺序详解

     项目:3个filter,3个servlet,匹配的url路径/hello. 情况1:servlet没加<load-on-startup></load-on-startup>情 ...

  6. Java静态导入

    Java静态导入 静态导入的语法是: import static ...; 静态导入的好处就是可以简化一些操作,例如System.out.println(…);就可以将其写入一个静态方法 import ...

  7. Java Script 学习笔记 -- jQuery

    一 jquery简介 1 jquery是什么  jQuery由美国人John Resig创建,至今已吸引了来自世界各地的众多 javascript高手加入其team. jQuery是继prototyp ...

  8. 利用css实现鼠标经过元素,下划线由中间向两边展开

    代码如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...

  9. vimtutor总结

    $vimtutor ================================================================================ W e l c o ...

  10. 飘逸的python - 装饰器的本质

    很多人把装饰器搞的很复杂,其实本质很简单. 首先,什么是装饰器呢?在代码中发现戴着@xxx帽子的,就是装饰器. 那要怎么自己定义一个装饰器呢? 其实任何一个接收一个参数的callable都可以用来做装 ...