CF633G Yash And Trees
用 dfs
序把树拍成区间,转化为区间问题。
建线段树,维护区间 bitset
表示一个取模后的数是否在区间内出现过。
答案即为区间的 bitset
质数集的 bitset
得到的 bitset
中 的个数。
时间复杂度 。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
inline ll read()
{
ll x = 0, f = 1;
char c = getchar();
while (c < '0' || c > '9')
{
if (c == '-')
f = -1;
c = getchar();
}
while (c >= '0' && c <= '9')
x = x * 10ll + c - '0', c = getchar();
return x * f;
}
const int _ = 1e5 + 10;
int n, m, q, a[_];
bitset<1005> full, tr[_ << 2], ans, pr;
int lz[_ << 2];
int id[_], dfn[_], ed[_], cnt;
vector<int> d[_];
void dfs(int u, int fa)
{
id[++cnt] = u, dfn[u] = cnt;
for(int v : d[u]) if(v != fa) dfs(v, u);
ed[u] = cnt;
}
void pushup(int o)
{
tr[o] = tr[o << 1] | tr[o << 1 | 1];
}
void tag(int o, int v)
{
lz[o] += v;
if(lz[o] >= m) lz[o] -= m;
tr[o] = ((tr[o] << v) & full) | (tr[o] >> (m - v));
}
void pushdown(int o)
{
if(lz[o])
tag(o << 1, lz[o]), tag(o << 1 | 1, lz[o]), lz[o] = 0;
}
void build(int o, int l, int r)
{
if(l == r)
{
tr[o].reset();
tr[o].set(a[id[l]]);
return;
}
int mid = (l + r) >> 1;
build(o << 1, l, mid), build(o << 1 | 1, mid + 1, r);
pushup(o);
}
void update(int o, int l, int r, int L, int R, int v)
{
if(r < L || l > R) return;
if(L <= l && r <= R) return tag(o, v), void();
pushdown(o);
int mid = (l + r) >> 1;
if(L <= mid)
update(o << 1, l, mid, L, R, v);
if(R > mid)
update(o << 1 | 1, mid + 1, r, L, R, v);
pushup(o);
}
void query(int o, int l, int r, int L, int R)
{
if(r < L || l > R) return;
if(L <= l && r <= R) return ans |= tr[o], void();
pushdown(o);
int mid = (l + r) >> 1;
if(L <= mid) query(o << 1, l, mid, L, R);
if(R > mid) query(o << 1 | 1, mid + 1, r, L, R);
pushup(o);
}
signed main()
{
n = read(), m = read();
for(int i = 0; i < m; ++i) full.set(i);
for(int i = 1; i <= n; ++i) a[i] = read() % m;
for(int i = 1, u, v; i < n; ++i)
{
u = read(), v = read();
d[u].push_back(v);
d[v].push_back(u);
}
q = read();
dfs(1, 0);
build(1, 1, n);
for(int i = 2; i < m; ++i) pr.set(i);
for(int i = 2; i < m; ++i)
if(pr[i])
for(int j = i * 2; j <= m; j += i)
pr.reset(j);
int op, x, y;
while(q--)
{
op = read();
if(op == 1)
{
x = read(), y = read() % m;
update(1, 1, n, dfn[x], ed[x], y);
}
else
{
x = read();
ans.reset();
query(1, 1, n, dfn[x], ed[x]);
cout << (ans & pr).count() << "\n";
}
}
return 0;
}
本文来自博客园,作者:蒟蒻orz,转载请注明原文链接:https://www.cnblogs.com/orzz/p/18121942