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

zoj_3911 Prime Query

2015-10-12 00:24 453 查看
简单的线段树,但是有坑就是输入时要注意有空格,就这一点来说我觉得出题人有点脑残!!!

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long LL;
#define INF 0x3f3f3f3f
#define N 100005
#define MAX 10000005
int solve;
struct node
{
int left;
int right;
int flag;
int value;
int sum;
};
node tree[N*4];
bool prime[MAX]; //判断p[i]中的i是否为素数

void prim_num() // 筛选法打素数表
{
int i,j;
prime[1] = prime[0] = false;
for(i=2; i<MAX; i++)
prime[i] = true;
for(i=2; i<MAX; i++)
{
for(j=i+i; j<MAX; j+=i)
{
if(prime[i])
prime[j]=false;
}
}
}
void build_tree(int l, int r, int p)
{
tree[p].left = l;
tree[p].right = r;
tree[p].flag = 0;
if(l == r)
{
scanf("%d", &tree[p].value);
tree[p].flag = 1;
return ;
}
int mid = (tree[p].left + tree[p].right) / 2;
build_tree(l, mid, p*2);
build_tree(mid+1, r, p*2+1);
}
void add(int k, int p, int value)
{
if(tree[p].left == k && tree[p].right == k)
{
tree[p].value += value;
return ;
}
if(tree[p].flag)
{
tree[p].flag = 0;
tree[p*2].flag = 1;
tree[p*2+1].flag = 1;
tree[p*2].value = tree[p].value;
tree[p*2+1].value = tree[p].value;
}
int mid = (tree[p].left + tree[p].right) / 2;
if(k<=mid)
add(k, p*2, value);
else
add(k, p*2+1, value);
}
void Replace(int l, int r, int p, int value)
{
if(tree[p].left == l && tree[p].right == r)
{
tree[p].flag = 1;
tree[p].value = value;
return ;
}
if(tree[p].flag)
{
tree[p].flag = 0;
tree[p*2].flag = 1;
tree[p*2+1].flag = 1;
tree[p*2].value = tree[p].value;
tree[p*2+1].value = tree[p].value;
}
int mid = (tree[p].right + tree[p].left) / 2;
if(r<=mid)
Replace(l, r, p*2, value);
else if(l >=mid+1)
Replace(l, r, p*2+1, value);
else
{
Replace(l, mid, p*2, value);
Replace(mid+1, r, p*2+1, value);
}
}
void Query(int l, int r, int p)
{
if(tree[p].left == l && tree[p].right == r && tree[p].flag)
{
if(prime[tree[p].value])
solve += (tree[p].right - tree[p].left + 1);
return ;
}
if(tree[p].flag)
{
tree[p*2].flag = 1;
tree[p*2+1].flag = 1;
tree[p*2].value = tree[p].value;
tree[p*2+1].value = tree[p].value;
}
int mid = (tree[p].right + tree[p].left) / 2;
if(r<=mid)
Query(l, r, p*2);
else if(l >= mid+1)
Query(l, r, p*2+1);
else
{
Query(l, mid, p*2);
Query(mid+1, r, p*2+1);
}
}
int main()
{
char str[100];
prim_num();
int T, n, m , ans, tmp, l, r, d, value;
scanf("%d", &T);
while(T--)
{
scanf("%d%d", &n, &m);
build_tree(1, n, 1);
for(int i=0; i<m; i++)
{
int k;
scanf("%s", &str);
for(k=0; str[k]!='\0'; k++)
if(str[k] >='A' && str[k]<='Z')
break;
if(str[k] == 'A')
{
scanf("%d%d",&value, &d);
add(d, 1, value);
}
else if(str[k] == 'R')
{
scanf("%d%d%d", &value, &l, &r);
Replace(l, r, 1, value);
}
else
{
solve = 0;
scanf("%d%d", &l, &r);
Query(l, r, 1);
printf("%d\n", solve);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  zoj 线段树