您的位置:首页 > 产品设计 > UI/UE

ZOJ 3911 Prime Query (线段树+单点更新+区间lazy更新+素数判断计数)

2016-01-26 12:31 561 查看
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 l   l位置的数加上v

R a l r 将[l,r]之间的数都变为a    ps:刚开始看的时候没认真,看成了加上a,汗= =!

Q l r 查询[l,r]之间的素数的个数

思路:先打一个素数表,然后结构体中加一个val记录当前值,其他的和普通的区间更新差不多,只是在向下更新和中间修改的时候判定一下素数

ac代码:

#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stack>
#include<set>
#include<queue>
#include<vector>
#include<iostream>
#include<algorithm>
using namespace std;
#define MAXN 10000010
#define LL long long
#define ll __int64
#define INF 0xfffffff
#define mem(x) memset(x,0,sizeof(x))
#define PI acos(-1)
struct s
{
int left;
int right;
int sum;
int val;
int lazy;
}tree[500000];
int v[MAXN];
void isprime()
{
int i,j;
mem(v);
v[0]=v[1]=1;
for(i=2;i<MAXN;i++)
{
if(!v[i])
{
for(j=i*2;j<MAXN;j+=i)
{
v[j]=1;
}
}
}
}
void pushdown(int i)
{
if(tree[i].lazy)
{
tree[i].val=tree[i].lazy;
tree[i*2].val=tree[i].lazy;
tree[i*2+1].val=tree[i].lazy;
tree[i*2].lazy=tree[i].lazy;
tree[i*2+1].lazy=tree[i].lazy;
if(v[tree[i].lazy])
{
tree[i*2].sum=tree[i*2+1].sum=0;
}
else
{
int mid=(tree[i].left+tree[i].right)/2;
tree[i*2].sum=mid-tree[i].left+1;
tree[i*2+1].sum=tree[i].right-mid;
}
tree[i].lazy=0;
}
}
void build(int l,int r,int i)
{
tree[i].left=l;
tree[i].right=r;
tree[i].lazy=0;
if(l==r)
{
scanf("%d",&tree[i].val);
tree[i].sum=v[tree[i].val]?0:1;
}
else
{
int mid=(l+r)/2;
build(l,mid,i*2);
build(mid+1,r,i*2+1);
tree[i].sum=tree[i*2].sum+tree[i*2+1].sum;
}
}
void add(int a,int c,int i)
{
int mid=(tree[i].left+tree[i].right)/2;
if(tree[i].left==tree[i].right&&tree[i].left==a)
{
tree[i].val+=c;
tree[i].sum=v[tree[i].val]?0:1;
return ;
}
pushdown(i);
if(a<=mid)
add(a,c,i*2);
else
add(a,c,i*2+1);
tree[i].sum=tree[i*2].sum+tree[i*2+1].sum;
}
void update(int l,int r,int c,int i)
{
int mid=(tree[i].right+tree[i].left)/2;
if(tree[i].left==l&&tree[i].right==r)
{
tree[i].lazy=c;
tree[i].val=c;
int t=v[c]?0:1;
tree[i].sum=t*(tree[i].right-tree[i].left+1);
return;
}
pushdown(i);
if(r<=mid)
{
update(l,r,c,i*2);
}
else if(l>mid)
{
update(l,r,c,i*2+1);
}
else
{
update(l,mid,c,i*2);
update(mid+1,r,c,i*2+1);
}
tree[i].sum=tree[i*2].sum+tree[i*2+1].sum;
}
int query(int l,int r,int i)
{
int mid=(tree[i].left+tree[i].right)/2;
if(tree[i].left==l&&tree[i].right==r)
{
return tree[i].sum;
}
pushdown(i);
if(r<=mid)
return query(l,r,i*2);
else if(l>mid)
return query(l,r,i*2+1);
else
return query(l,mid,i*2)+query(mid+1,r,i*2+1);
}
int main()
{
isprime();
int i;
int a,b,n,m;
int t;
char ch[10];
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
build(1,n,1);
while(m--)
{
int a,b,c;
scanf("%s",ch);
if(ch[0]=='A')
{
scanf("%d%d",&a,&b);
add(b,a,1);
}
else if(ch[0]=='R')
{
scanf("%d%d%d",&a,&b,&c);
update(b,c,a,1);
}
else if(ch[0]=='Q')
{
scanf("%d%d",&a,&b);
printf("%d\n",query(a,b,1));
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: