题目大意:

给你一棵树,根节点为1

有2种操作,第一种是给u节点所在的子树的所有节点的权值+x

第二种是询问,假设v是子树u中的节点,有多少种质数p满足av = p + m·k

做法:维护子树信息显然dfs序,考虑用线段树维护一个区间内有哪些值

每个区间用一个bitset维护

这里有一个小技巧,bitset都+x然后%m,可以bt2[k]=(bt2[k]<<y)|(bt2[k]>>(m-y));

然后求出区间的bitset,和质数的bitset&一下,求1的个数即可

代码如下:

#include<bits/stdc++.h>
#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[++kk].nxt=head[x];e[kk].to=y;head[x]=kk;}
inline void init(){
for (int i=2;i<m;i++){
if (!vis[i]) pr[++tot]=i;
for (int j=1;j<=tot;j++){
if (i*pr[j]>=m) break;
vis[i*pr[j]]=true;
if (i%pr[j]==0) break;
}
}
}
void dfs(int u,int fa){
sz[u]=1;dfn[u]=++tim1;reall[tim1]=a[u];
for (int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
if (v==fa) continue;
dfs(v,u);sz[u]+=sz[v];
}
}
void build(int k,int l,int r){
if (l==r){bt2[k][reall[l]]=1;return;}
int mid=(l+r)>>1;
build(k*2,l,mid);build(k*2+1,mid+1,r);
bt2[k]=bt2[k*2]|bt2[k*2+1];
}
void update(int k,int y){y%=m;bt2[k]=(bt2[k]<<y)|(bt2[k]>>(m-y));}
inline void pushdown(int k){
if (!ee[k]) return;
ee[k*2]=(ee[k*2]+ee[k])%m;
ee[k*2+1]=(ee[k*2+1]+ee[k])%m;
update(k*2,ee[k]);update(k*2+1,ee[k]);
ee[k]=0;
}
void add(int k,int l,int r,int x,int y,int z){
if (l!=r) pushdown(k);
if (x<=l&&y>=r){update(k,z);ee[k]=(ee[k]+z)%m;return;}
int mid=(l+r)>>1;
if (y<=mid) add(k*2,l,mid,x,y,z);
else if (x>mid) add(k*2+1,mid+1,r,x,y,z);
else add(k*2,l,mid,x,mid,z),add(k*2+1,mid+1,r,mid+1,y,z);
bt2[k]=bt2[k*2]|bt2[k*2+1];
}
void query(int k,int l,int r,int x,int y){
if (l!=r) pushdown(k);
if (x<=l&&y>=r){bt3=bt3|bt2[k];return;}
int mid=(l+r)>>1;
if (y<=mid) query(k*2,l,mid,x,y);
else if (x>mid) query(k*2+1,mid+1,r,x,y);
else query(k*2,l,mid,x,mid),query(k*2+1,mid+1,r,mid+1,y);
}
int main(){
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++) scanf("%d",&a[i]),a[i]%=m;
for (int i=1;i<n;i++){
scanf("%d%d",&x,&y);
link(x,y);link(y,x);
}
init();
for (int j=1;j<=tot;j++) bt1[pr[j]]=1;
//printf("%d\n",(int)bt1.count());
dfs(1,-1);
//for (int i=1;i<=n;i++) printf("%d ",dfn[i]);puts("");
//for (int i=1;i<=n;i++) printf("%d ",reall[i]);puts("");
build(1,1,n);
//if (bt2[7][5]) puts("Yes1");
/*if (bt2[3][5]) puts("Yes1");//
if (bt2[3][1]) puts("Yes2");
if (bt2[2][7]) puts("YES1");
if (bt2[2][8]) puts("YES2");
if (bt2[2][0]) puts("YES3");
if (bt2[1][8]) puts("Yes1");
if (bt2[1][7]) puts("Yes2");
if (bt2[1][5]) puts("Yes3");
if (bt2[1][1]) puts("Yes4");
if (bt2[1][0]) puts("Yes5");*/
scanf("%d",&Q);
while (Q--){
scanf("%d%d",&opt,&x);
if (opt==1){
scanf("%d",&y);y%=m;
if (y) add(1,1,n,dfn[x],dfn[x]+sz[x]-1,y);
}
else {
/*if (bt2[1][0]) puts("Yes1");
if (bt2[1][9]) puts("Yes2");
if (bt2[1][7]) puts("Yes3");
if (bt2[1][3]) puts("Yes4");
if (bt2[1][2]) puts("Yes5");*/
bt3.reset();
query(1,1,n,dfn[x],dfn[x]+sz[x]-1);
//printf("%d\n",(int)bt3.count());
bt3=bt3&bt1;
printf("%d\n",(int)bt3.count());
}
}
return 0;
}

  

CF633G的更多相关文章

随机推荐

  1. Java的访问权限详解(3+1)public private protected default

    Java使用三个关键字在类的内部设定访问权限:public.private.protected.这些访问指定词(access specifier)决定了紧跟其后被定义的成员(方法或属性)可以被谁使用. ...

  2. [IDE工具配置]myeclipse 2014 专业版 安装 svn插件

    本文地址:http://blog.csdn.net/sushengmiyan/article/details/38342411 本文作者:sushengmiyan 团队合作的项目肯定少不了版本控制,那 ...

  3. SSH深度历险(三) EJB Session Bean有状态和无状态的区别与联系

    刚开始对两种sessionbean存在误解,认为有状态是实例一直存在,保存每次调用后的状态,并对下一次调用起作用,而认为无状态是每次调用实例化一次,不保留用户信息.仔细分析并用实践检验后,会发现,事实 ...

  4. [WinForm]dataGridView动态加载以本地图片显示列

    增加一个图片列: C# private void btnQuery_Click(object sender, EventArgs e) { StringBuilder sb=new StringBui ...

  5. 12_Android中HttpClient的应用,doGet,doPost,doHttpClientGet,doHttpClient请求,另外借助第三方框架实现网络连接的应用,

     准备条件, 编写一个web项目.编写一个servlet,若用户名为lisi,密码为123,则返回"登录成功",否则"登录失败".项目名为ServerIth ...

  6. Linux 中环境变量设置

    本文主要整理自以下博文: .bash_profile和.bashrc的什么区别及启动过程 linux环境变量设置方法总结(PATH/LD_LIBRARY_PATH) .bash_profile 和 . ...

  7. python 2.4 的字符串转时间(日期减法取间隔时间)

    python 2.4中datetime有strftime方法,而无strptime方法.不能对字符串进行格式转换.比如不能将"2013-10-22"转化为日期. 2.4中字符串转日 ...

  8. 使用MTL库求解最小二乘解

    最小二乘计算最优解不管是哪个行业肯定都用到的非常多.对于遥感图像处理中,尤其是对图像进行校正处理,关于控制点的几种校正模型中,都用到最小二乘来计算模型的系数.比如几何多项式,或者通过GCP求解RPC系 ...

  9. Saiku去掉登录模块

    1.修改applicationContext-saiku-webapp.xml <security:intercept-url pattern="/rest/**" acce ...

  10. Boosting 和梯度Boosting

    Boosting方法: Boosting这其实思想相当的简单,大概是,对一份数据,建立M个模型(比如分类),一般这种模型比较简单,称为弱分类器(weak learner)每次分类都将上一次分错的数据权 ...