http://codeforces.com/problemset/problem/633/G
给一个模数mod(<=1000) 两种操作
一是区间加值 二是查询区间有多少种取模后的素数
最暴力的想法就是对每个节点开一个1000大的数组 查询就看素数位置有多少是1 然后修改时把数组循环x次 肯定不行
但这正好是bitset的功能啊 把1000的数组换成bitset 修改时移位操作如下 bit[cur]=(bit[cur]<<val)|(bit[cur]>>(mod-val))
#include <bits/stdc++.h>
using namespace std;
struct node
{
int v;
int next;
};
bitset <1010> bit[400010];
bitset <1010> pre;
node edge[200010];
int laz[400010];
int val[100010],prime[1010],first[100010],mp1[100010],mp2[100010],sum[100010];
int n,mod,q,num;
void init()
{
int i,j;
prime[0]=1,prime[1]=1;
for(i=2;i*i<mod;i++)
{
if(prime[i]==0) for(j=i+i;j<mod;j+=i) prime[j]=1;
}
for(i=0;i<mod;i++) if(prime[i]==0) pre.set(i);
}
void addedge(int u,int v)
{
edge[num].v=v;
edge[num].next=first[u];
first[u]=num++;
}
void dfs(int cur,int fa)
{
int i,v;
num++;
mp1[cur]=num,mp2[num]=cur,sum[cur]=1;
for(i=first[cur];i!=-1;i=edge[i].next)
{
v=edge[i].v;
if(v!=fa)
{
dfs(v,cur);
sum[cur]+=sum[v];
}
}
}
void pushup(int cur)
{
bit[cur]=bit[2*cur]|bit[2*cur+1];
}
void pushdown(int cur)
{
int val;
val=laz[cur];
if(val!=0)
{
bit[2*cur]=(bit[2*cur]<<val)|(bit[2*cur]>>(mod-val));
laz[2*cur]=(laz[2*cur]+val)%mod;
bit[2*cur+1]=(bit[2*cur+1]<<val)|(bit[2*cur+1]>>(mod-val));
laz[2*cur+1]=(laz[2*cur+1]+val)%mod;
laz[cur]=0;
}
}
//stu[rt] = (stu[rt] << x) | (stu[rt] >> (m - x));
void build(int l,int r,int cur)
{
int m;
if(l==r)
{
bit[cur].set(val[mp2[l]]);
return;
}
m=(l+r)/2;
build(l,m,2*cur);
build(m+1,r,2*cur+1);
pushup(cur);
}
void update(int pl,int pr,int val,int l,int r,int cur)
{
int m;
if(pl<=l&&r<=pr)
{
bit[cur]=(bit[cur]<<val)|(bit[cur]>>(mod-val));
laz[cur]=(laz[cur]+val)%mod;
return;
}
pushdown(cur);
m=(l+r)/2;
if(pl<=m) update(pl,pr,val,l,m,2*cur);
if(pr>m) update(pl,pr,val,m+1,r,2*cur+1);
pushup(cur);
}
bitset <1010> query(int pl,int pr,int l,int r,int cur)
{
bitset <1010> res;
int m;
if(pl<=l&&r<=pr) return bit[cur];
pushdown(cur);
m=(l+r)/2;
if(pl<=m) res|=query(pl,pr,l,m,2*cur);
if(pr>m) res|=query(pl,pr,m+1,r,2*cur+1);
return res;
}
int main()
{
bitset <1010> res;
int i,u,v,tp,x;
scanf("%d%d",&n,&mod);
init();
for(i=1;i<=n;i++)
{
scanf("%d",&val[i]);
val[i]%=mod;
}
memset(first,-1,sizeof(first));
num=0;
for(i=1;i<=n-1;i++)
{
scanf("%d%d",&u,&v);
addedge(u,v);
addedge(v,u);
}
num=0;
dfs(1,0);
build(1,n,1);
scanf("%d",&q);
while(q--)
{
scanf("%d",&tp);
if(tp==1)
{
scanf("%d%d",&u,&x);
x%=mod;
update(mp1[u],mp1[u]+sum[u]-1,x,1,n,1);
}
else
{
scanf("%d",&u);
res=query(mp1[u],mp1[u]+sum[u]-1,1,n,1);
printf("%d\n",(res&pre).count());
}
}
return 0;
}