树链剖分题目
LCA模板
int n, m;
int fa[MXN], sz[MXN], dep[MXN], son[MXN], top[MXN];
std::vector<int> mp[MXN];
void dfs1(int u,int ba,int d) {
dep[u] = d; fa[u] = ba; sz[u] = 1; son[u] = 0;
for(auto v: mp[u]) {
if(v == ba) continue;
dfs1(v, u, d + 1);
sz[u] += sz[v];
if(sz[v] > sz[son[u]]) son[u] = v;
}
}
void rdfs(int u,int ba) {
if(son[u]) {
top[son[u]] = top[u];
rdfs(son[u], u);
}
for(auto v: mp[u]) {
if(v == ba || v == son[u]) continue;
top[v] = v;
rdfs(v, u);
}
}
int LCA(int x,int y) {
while(top[x] != top[y]) {
if(dep[top[x]] < dep[top[y]]) swap(x, y);
x = fa[top[x]];
}
return dep[x] < dep[y]? x: y;
}
void solve() {
dfs1(1, 1, 1);
top[1] = 1;
rdfs(1, 1);
}
function<void(LL,LL)> dfs = [&](LL u, LL p) {
seg[u].first = ++step;
for(LL i = 0; i < G[u].size(); i++) {
LL &v = G[u][i];
if(v == p) continue;
dfs(v, u);
}
seg[u].second = step;
};
P3384[模板]树链剖分
#include<bits/stdc++.h>
#define lowbit(x) (x&(-(x)))
#define lson rt<<1
#define rson rt<<1|1
#define mme(a,b) memset((a),(b),sizeof((a)))
#define fuck(x) cout<<"* "<<x<<"\n"
#define iis std::ios::sync_with_stdio(false)
#define fi first
#define se second
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const int MOD = 998244353;
const int N = 1e5 + 7;
const int MX = 2e5 + 7;
int n, m, q, mod, root;
struct Tree{
int l,r,d,Sum,lazy;
}sgt[N<<2];
int ar[N];
struct lp{
int v,nex;
}cw[MX];
int head[MX],tot;
int inde;
int sz[MX],top[MX],son[MX],dep[MX],faz[MX];
int tid[MX],rnk[MX],rtid[MX];//id->dfsid//dfsid->id//lastid
void init(){
tot=-1;inde=0;
mme(head,-1);mme(son,-1);
mme(sz,0);mme(dep,0);mme(faz,0);mme(top,0);
mme(tid,0);mme(rtid,0);mme(rnk,0);
}
void push_up(int rt){
sgt[rt].Sum=(sgt[lson].Sum+sgt[rson].Sum)%mod;
}
void push_down(int rt){
if(sgt[rt].lazy){
int c = sgt[rt].lazy;
sgt[lson].lazy=(sgt[lson].lazy+sgt[rt].lazy)%mod;
sgt[rson].lazy=(sgt[rson].lazy+sgt[rt].lazy)%mod;
sgt[lson].Sum=(sgt[lson].Sum+sgt[lson].d*c%mod)%mod;
sgt[rson].Sum=(sgt[rson].Sum+sgt[rson].d*c%mod)%mod;
sgt[rt].lazy=0;
}
}
void build(int l,int r,int rt){
sgt[rt].l=l;sgt[rt].r=r;
sgt[rt].d=r-l+1;
sgt[rt].lazy=0;
if(l==r){
sgt[rt].Sum=ar[rnk[l]];
return;
}
int mid=(l+r)>>1;
build(l,mid,lson);build(mid+1,r,rson);
push_up(rt);
}
void update(int L,int R,int c,int rt){
int l = sgt[rt].l,r=sgt[rt].r,mid=(l+r)>>1;
if(sgt[rt].l>R||sgt[rt].r<L)return;
if(L<=l&&r<=R){
sgt[rt].lazy=(c+sgt[rt].lazy)%mod;
sgt[rt].Sum=(sgt[rt].Sum+sgt[rt].d*c%mod)%mod;
return;
}
if(sgt[rt].l==sgt[rt].r)return;
push_down(rt);
if(L<=mid)update(L,R,c,lson);
if(R>mid)update(L,R,c,rson);
push_up(rt);
}
int query(int L,int R,int rt){
int l = sgt[rt].l,r=sgt[rt].r,mid=(l+r)>>1;
if(L<=l&&r<=R){
return sgt[rt].Sum;
}
if(sgt[rt].l>R||sgt[rt].r<L)return 0;
if(sgt[rt].l==sgt[rt].r)return 0;
push_down(rt);
int _sum = 0;
if(L<=mid)_sum = query(L,R,lson)%mod;
if(R>mid)_sum=(_sum+query(L,R,rson))%mod;
return _sum;
}
void dfs1(int u,int fat,int depth){
dep[u] = depth;faz[u] = fat;sz[u] = 1;
son[u] = 0;
for(int i=head[u];~i;i=cw[i].nex){
int v = cw[i].v;
if(v==fat)continue;
dfs1(v,u,depth+1);
sz[u] += sz[v];
if(sz[v]>sz[son[u]]){
son[u] = v;
}
}
}
void dfs2(int u,int t){
tid[u] = ++inde;
rnk[inde]=u;
if(son[u]){
top[son[u]] = top[u];
dfs2(son[u],u);
}
for(int i=head[u];~i;i=cw[i].nex){
int v = cw[i].v;
if(v!=son[u]&&v!=faz[u]){
top[v]=v;
dfs2(v,u);
}
}
rtid[u]=inde;
}
int path_query(int x,int y){
int ans=0;
int fx=top[x],fy=top[y];
while(fx!=fy){
if(dep[fx]>=dep[fy]){
ans=(ans+query(tid[fx],tid[x],1))%mod;
x=faz[fx];
}else {
ans=(ans+query(tid[fy],tid[y],1))%mod;
y=faz[fy];
}
fx=top[x],fy=top[y];
}
if(tid[x]<tid[y]){
ans=(ans+query(tid[x],tid[y],1))%mod;
}else {
ans=(ans+query(tid[y],tid[x],1))%mod;
}
return ans;
}
void path_update(int x,int y,int c){
int fx=top[x],fy=top[y];
while(fx!=fy){
if(dep[fx]>dep[fy]){
update(tid[fx],tid[x],c,1);
x=faz[fx];
}else {
update(tid[fy],tid[y],c,1);
y=faz[fy];
}
fx=top[x],fy=top[y];
}
if(tid[x]<tid[y]){
update(tid[x],tid[y],c,1);
}else {
update(tid[y],tid[x],c,1);
}
}
void add_edge(int u,int v){
cw[++tot].v=v;cw[tot].nex=head[u];
head[u]=tot;
cw[++tot].v=u;cw[tot].nex=head[v];
head[v]=tot;
}
void pre_build(){
dfs1(root,root,1);
top[root]=root;
dfs2(root,root);
build(1,n,1);
}
int main(){
while(~scanf("%d%d%d%d",&n,&q,&root,&mod)){
init();
for(int i=1;i<=n;++i){
scanf("%d",&ar[i]);
ar[i]%=mod;
}
for(int i=1,u,v;i<n;++i){
scanf("%d%d",&u,&v);
add_edge(u,v);
}
pre_build();
while(q--){
int op;scanf("%d",&op);
int u,v,w;
if(op==1){
scanf("%d%d%d",&u,&v,&w);
w%=mod;
path_update(u,v,w);
}else if(op==2){
scanf("%d%d",&u,&v);
printf("%d\n", path_query(u,v));
}else if(op==3){
scanf("%d%d",&u,&w);
w%=mod;
update(tid[u],rtid[u],w,1);
}else if(op==4){
scanf("%d",&u);
printf("%d\n", query(tid[u],rtid[u],1));
}
}
}
return 0;
}
牛客国庆集训派对Day6-I-清明梦超能力者黄YY
#include<bits/stdc++.h>
#define lson rt<<1
#define rson rt<<1|1
#define fi first
#define se second
#define mme(a,b) memset((a),(b),sizeof((a)))
#define iis std::ios::sync_with_stdio(false)
#define Mod(a, b) a<b?a:a%b+b
using namespace std;
typedef long long LL;
const int MXN = 2e5 + 7;
const int mod = 1000000007;
const int INF = 0x3f3f3f3f;
int n, m, k;
struct one{
int u, v, c;
}opt[MXN];
std::vector<int> mp[MXN];
int fa[MXN], dep[MXN], son[MXN], top[MXN], tid[MXN], rtid[MXN], siz[MXN];
int inde;
int rnk[MXN];
int sum[MXN<<2], flag[MXN<<2];
int ans[MXN], res[MXN<<2];
void build(int l,int r,int rt) {
sum[rt] = 0; flag[rt] = 0;
if(l == r) return;
int mid = (l + r) >> 1;
build(l,mid,lson), build(mid+1,r,rson);
}
void push_up(int rt) {
if(sum[lson] < k && sum[rson] < k) {
sum[rt] = max(sum[lson], sum[rson]);
}
}
void push_down(int rt) {
flag[lson] += flag[rt];
flag[rson] += flag[rt];
sum[lson] += flag[rt];
sum[rson] += flag[rt];
flag[rt] = 0;
}
void fuck(int c,int l,int r,int rt) {
if(sum[rt] != k) return;
if(l == r) {
ans[rnk[l]] = c;
sum[rt] = -INF;
return;
}
push_down(rt);
int mid = (l + r) >> 1;
fuck(c, l, mid, lson);
fuck(c, mid + 1, r, rson);
push_up(rt);
}
void updata(int L,int R,int c,int l,int r,int rt) {
if(L <= l && r <= R) {
++ flag[rt];
++ sum[rt];
fuck(c, l, r, rt);
return;
}
push_down(rt);
int mid = (l + r) >> 1;
if(L > mid) updata(L,R,c,mid+1,r,rson);
else if(R <= mid) updata(L,R,c,l,mid,lson);
else {
updata(L,mid,c,l,mid,lson);
updata(mid+1,R,c,mid+1,r,rson);
}
push_up(rt);
}
void dfs_1(int u,int ba,int D) {
fa[u] = ba; dep[u] = D; son[u] = 0; siz[u] = 1;
for(auto v: mp[u]) {
if(v == ba) continue;
dfs_1(v, u, D+1);
siz[u] += siz[v];
if(siz[v] > siz[son[u]]) son[u] = v;
}
}
void dfs_2(int u,int ba) {
tid[u] = ++inde;
rnk[inde] = u;
if(son[u]) {
top[son[u]] = top[u];
dfs_2(son[u], u);
}
for(auto v: mp[u]) {
if(v == ba || v == son[u]) continue;
top[v] = v;
dfs_2(v, u);
}
rtid[u] = inde;
}
void updata_path(int x,int y,int c) {
int fx = top[x], fy = top[y];
while(fx != fy) {
if(dep[fx] <= dep[fy]) swap(fx,fy),swap(x,y);
updata(tid[fx], tid[x], c, 1, n, 1);
x = fa[fx];
fx = top[x], fy = top[y];
}
if(tid[x] >= tid[y]) swap(x, y);
updata(tid[x], tid[y], c, 1, n, 1);
}
int main() {
scanf("%d%d%d", &n, &m, &k);
for(int i = 1, a, b; i < n; ++i) {
scanf("%d%d", &a, &b);
mp[a].push_back(b);
mp[b].push_back(a);
}
for(int i = 0, u, v, c; i < m; ++i) {
scanf("%d%d%d", &opt[i].u, &opt[i].v, &opt[i].c);
}
dfs_1(1, 1, 1);
top[1] = 1;
dfs_2(1, 1);
build(1, n, 1);
for(int i = m-1; i >= 0; --i) {
updata_path(opt[i].u,opt[i].v,opt[i].c);
}
for(int i = 1; i < n; ++i) {
printf("%d ", ans[i]);
}
printf("%d\n", ans[n]);
return 0;
}
ACMer,无怨无悔