http://acm.hit.edu.cn/hoj/problem/view?id=1867

Source : HCPC 2005 Spring
 Time limit : 2 sec Memory limit : 32 M

Submitted : 3490, Accepted : 796

Jerry是一家公司销售部门的经理。这家公司有很多连锁店,编号为1,2,3,... Jerry每天必须关注每家连锁店的商品数量及其变化,一项很乏味的工作。在连锁店比较少的时候,Jerry喜欢计算编号在[i,j]区间内的连锁店中商品数量为素数的有多少家,但是现在连锁店的数量急剧增长,计算量很大,Jerry很难得出结果。

输入格式
题目有多组输入。每组输入第一行有三个整数:C 连锁店的数量 N 指令的条数 M 每家连锁店初始的商品数量
接下来有N行,每行有一条指令。指令的格式为:
0 x y 连锁店x的商品数量变化值为y,y > 0商品数量增加, y < 0减少
1 i j 输出编号在[i,j]区间内的连锁店中商品数量为素数的有多少家
1 <= i, x, j < 1000000 连锁店中的商品数量a满足 0 <= a < 10000000,C = N = M = 0标志输入结束

输出格式
对于每组输入,输出它的序号。对于一组输入中的1指令输出要求的整数。每组输出后打印一行空行。

样例输入

100000 4 4
0 1 1
1 4 10
0 11 3
1 1 11 20 3 0
1 1 20
0 3 3
1 1 20 0 0 0

样例输出

CASE #1:
0
2 CASE #2:
0
1 树状数组+判断素数(2的一b的空间、、)
 #include <algorithm>
#include <cstring>
#include <cstdio> using namespace std; const int maxn();
int n,t,sta,val[maxn]; int tr[maxn];
#define lowbit(x) (x&((~x)+1))
inline void Update(int i,int x)
{
for(;i<=n;i+=lowbit(i)) tr[i]+=x;
}
inline int Query(int x)
{
int ret=;
for(;x;x-=lowbit(x)) ret+=tr[x];
return ret;
} inline bool if_prime(int x)
{
if(x<) return false;
for(int i=;i*i<=x;i++)
if(x%i==) return false;
return true;
} int main()
{
for(int i=;scanf("%d%d%d",&n,&t,&sta);i++)
{
if(!n&&!t&&!sta) break;
memset(tr,,sizeof(tr));
printf("CASE #%d:\n",i);
bool flag=; if(if_prime(sta)) flag=;
for(int i=;i<=n;i++)
{
val[i]=sta;
if(flag) Update(i,);
}
for(int a,b,c;t--;)
{
scanf("%d%d%d",&a,&b,&c);
if(a==)
{
bool if1=if_prime(val[b]);
val[b]+=c;
bool if2=if_prime(val[b]);
if(!if1&&if2) Update(b,);
if(if1&&!if2) Update(b,-);
}
else printf("%d\n",Query(c)-Query(b-));
}
printf("\n");
}
return ;
}
05-25 21:42