hoj1867: 经理的烦恼
hoj1867: http://acm.hit.edu.cn/hoj/problem/view?id=1867
题意:c个连锁店,n条指令,每间店的初始商品数量。有两种指令:x,y,z,若x=0,表示第y个店的数目增加z,若x=1,表示查询店y到z中商品数量为素数的个数
解法:树状数组
code:
#include<iostream> #include<cstdio> #include<cstdlib> const int maxn=1000010; int a[maxn],v[maxn]; //a为商品数目,v为素数个数 int prime(int x) //判断素数 { if(x<=1)return 0; else { for(int i=2;i*i<=x;i++) { if(x%i==0) return 0; } return 1; } } int lowbit(int x) { return x&(-x); } void insert(int x,int y) //更新点及其父节点 { while(x<maxn) { v[x]+=y; x=x+lowbit(x); } } int sum(int x) //求和 { int s=0; while(x>0) { s=s+v[x]; x-=lowbit(x); } return s; } int main() { int c,n,m,x,y,z,cas=0; while(1) { cas++; scanf("%d%d%d",&c,&n,&m); if(c==n&&n==m)break; memset(v,0,sizeof(v)); a[0]=0; int t=prime(m); for(int i=1;i<=c;i++) { if(t) insert(i,1); a[i]=m; } printf("CASE #%d:\n",cas); for(int i=0;i<n;i++) { scanf("%d%d%d",&x,&y,&z); if(x==0) { if(prime(a[y])) //若原来为素数,因为要改变了,所以先改为非素数,所以-1 insert(y,-1); a[y]+=z; if(prime(a[y])) //若改变后为素数,则更新 insert(y,1); } else printf("%d\n",sum(z)-sum(y-1)); //y到z商品数为素数的店个数 } printf("\n"); } } /*input: 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 output: CASE #1: 0 2 CASE #2: 0 1 */