题目大意:
给你一棵树,根节点为1
有2种操作,第一种是给u节点所在的子树的所有节点的权值+x
第二种是询问,假设v是子树u中的节点,有多少种质数p满足av = p + m·k
做法:维护子树信息显然dfs序,考虑用线段树维护一个区间内有哪些值
每个区间用一个bitset维护
这里有一个小技巧&#xff0c;bitset都&#43;x然后%m&#xff0c;可以bt2[k]&#61;(bt2[k]<
然后求出区间的bitset&#xff0c;和质数的bitset&一下&#xff0c;求1的个数即可
代码&#xff1a;
#include
#define N 500005
using namespace std;bool vis[N];
int n,m,Q,x,y,opt,tim1,kk,tot,head[N],a[N],dfn[N],sz[N],pr[N];
bitset<1005>bt1,bt2[N],bt3;int ee[N],reall[N];
struct Tree{int nxt,to;}e[N];
inline void link(int x,int y){e[&#43;&#43;kk].nxt&#61;head[x];e[kk].to&#61;y;head[x]&#61;kk;}
inline void init(){for (int i&#61;2;i
}
void dfs(int u,int fa){sz[u]&#61;1;dfn[u]&#61;&#43;&#43;tim1;reall[tim1]&#61;a[u];for (int i&#61;head[u];i;i&#61;e[i].nxt){int v&#61;e[i].to;if (v&#61;&#61;fa) continue;dfs(v,u);sz[u]&#43;&#61;sz[v];}
}
void build(int k,int l,int r){if (l&#61;&#61;r){bt2[k][reall[l]]&#61;1;return;}int mid&#61;(l&#43;r)>>1;build(k*2,l,mid);build(k*2&#43;1,mid&#43;1,r);bt2[k]&#61;bt2[k*2]|bt2[k*2&#43;1];
}
void update(int k,int y){y%&#61;m;bt2[k]&#61;(bt2[k]<
inline void pushdown(int k){if (!ee[k]) return;ee[k*2]&#61;(ee[k*2]&#43;ee[k])%m;ee[k*2&#43;1]&#61;(ee[k*2&#43;1]&#43;ee[k])%m;update(k*2,ee[k]);update(k*2&#43;1,ee[k]);ee[k]&#61;0;
}
void add(int k,int l,int r,int x,int y,int z){if (l!&#61;r) pushdown(k);if (x<&#61;l&&y>&#61;r){update(k,z);ee[k]&#61;(ee[k]&#43;z)%m;return;}int mid&#61;(l&#43;r)>>1;if (y<&#61;mid) add(k*2,l,mid,x,y,z);else if (x>mid) add(k*2&#43;1,mid&#43;1,r,x,y,z);else add(k*2,l,mid,x,mid,z),add(k*2&#43;1,mid&#43;1,r,mid&#43;1,y,z);bt2[k]&#61;bt2[k*2]|bt2[k*2&#43;1];
}
void query(int k,int l,int r,int x,int y){if (l!&#61;r) pushdown(k);if (x<&#61;l&&y>&#61;r){bt3&#61;bt3|bt2[k];return;}int mid&#61;(l&#43;r)>>1;if (y<&#61;mid) query(k*2,l,mid,x,y);else if (x>mid) query(k*2&#43;1,mid&#43;1,r,x,y);else query(k*2,l,mid,x,mid),query(k*2&#43;1,mid&#43;1,r,mid&#43;1,y);
}
int main(){scanf("%d%d",&n,&m);for (int i&#61;1;i<&#61;n;i&#43;&#43;) scanf("%d",&a[i]),a[i]%&#61;m;for (int i&#61;1;i