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


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;
}


你可能感兴趣的:(ZOJ 3911 Prime Query (线段树+单点更新+区间lazy更新+素数判断计数))