题意

一棵树

多次修改,每次修改一个点到根的所有边的颜色,并询问现在有哪些颜色染了恰好$m$条边

题解:

稍加思考可以知道,从某个点到根节点的颜色数,均摊复杂度很低,因此,可以考虑珂朵莉树维护重链剖分

这里也记录一下珂朵莉树的代码

代码:

#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
#define ull unsigned long long
#define fi first
#define se second
#define pii pair<int,int>
#define all(x) x.begin(),x.end()
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define rep(ii,a,b) for(int ii=a;ii<=b;++ii)
#define per(ii,a,b) for(int ii=b;ii>=a;--ii)
#define forn(ii,x) for(int ii=head[x];ii;ii=edge[ii].next)
using namespace std;
const int maxn=2e5+20,maxm=2e6+10;
const int INF=0x3f3f3f3f;
const ll mod=1e9+7;
int casn,n,m,k,col[maxn],ans[maxn];
class odtree{public:
struct segnode{int l,r,c;bool operator <(const segnode &a)const{return r<a.r;}};
set<segnode> nodes;
void split(int pos){auto it=nodes.lower_bound({pos,pos});
if(it==nodes.end()||(it->l)>pos||(it->r)==pos) return ;
int l=it->l,r=it->r,c=it->c;
nodes.erase(it);nodes.insert({l,pos,c});nodes.insert({pos+1,r,c});
}
void update(int l,int r,int c){
split(l-1);split(r);
while(1){auto it=nodes.lower_bound({l,l});
if(it==nodes.end()||(it->l)>r) break;
if(it->c){--ans[col[it->c]];col[it->c]-=(it->r)-(it->l)+1;++ans[col[it->c]];}
nodes.erase(it);
}
--ans[col[c]];col[c]+=r-l+1;++ans[col[c]];
nodes.insert({l,r,c});
}
}tree;
namespace chain{
struct data_e{int to,next;}edge[maxn<<1];
int head[maxn],nume,mp[maxn];
int ltop[maxn],fa[maxn],deep[maxn];
int sz[maxn],remp[maxn],son[maxn],cnt;
inline void addedge(int a,int b){edge[++nume]={b,head[a]};head[a]=nume;}
void init(){rep(i,1,n) head[i]=0;cnt=nume=0;}
void dfs1(int now,int pre,int d){
deep[now]=d,fa[now]=pre,sz[now]=1,son[now]=0;
forn(i,now){int to=edge[i].to;
if(to!=pre) {
dfs1(to,now,d+1);sz[now]+=sz[to];
if(sz[to]>sz[son[now]]) son[now]=to;
}
}
}
void dfs2(int now,int pre,int sp){
ltop[now]=sp;mp[now]=++cnt;remp[cnt]=now;
if(son[now]) dfs2(son[now],now,sp);
forn(i,now){int to=edge[i].to;
if(to!=son[now]&&to!=pre) dfs2(to,now,to);
}
}
void gao(int st=1){dfs1(st,0,0);dfs2(st,0,st);}
void update(int now,int c){
while(now>1){
int l=max(mp[ltop[now]],2),r=mp[now];
if(l<=r) tree.update(l,r,c);
now=fa[ltop[now]];
}
}
};
int main() {IO;
cin>>n>>m>>k;
rep(i,1,n-1){int a,b;
cin>>a>>b;
chain::addedge(a,b);chain::addedge(b,a);
}
ans[0]=m;
chain::gao();
tree.nodes.insert({2,n,0});
while(k--){int a,b,c;
cin>>a>>b>>c;
chain::update(a,b);
cout<<ans[c]<<endl;
}
return 0;
}

最新文章

  1. Sass之坑Compass编译报错
  2. Stl源码剖析读书笔记之Alloc细节
  3. insertAfter的兼容性
  4. linux 截图利器-scrot
  5. [itint5]单词变换
  6. RFC3261--sip
  7. 常用的linux系统监控命令整理
  8. 微服务架构的基础框架选择:Spring Cloud还是Dubbo?
  9. django 前端模板继承显示model中使用choices的字段
  10. 【java规则引擎】《Drools7.0.0.Final规则引擎教程》第4章 4.5RHS语法
  11. 你真的理解PeopleSoft的Web概要(web profile)嘛
  12. Vue 组件中 移动 this.$el 的注意事项
  13. PAT 1015 德才论 (25)(代码+思路)
  14. Qt获取控件位置,坐标总结
  15. Realm的常规使用与线程中的坑
  16. javascript高性能
  17. Object.keys()的简单理解
  18. wx.grid.Grid
  19. 在Windows Python3.5 安装LightGBM
  20. *521. Longest Uncommon Subsequence I (bit manipulation 2^n)

热门文章

  1. 转载:用Jquery实现的图片预加载技术,可以实现有序加载和无序加载!
  2. JVN的理解
  3. H5软键盘兼容方案
  4. 网络流学习(转载自ssw 的博客)
  5. Webstorm的一些常用快捷键
  6. let 和 const 在for 循环中的使用
  7. CF 543C Remembering Strings
  8. WC2019冬眠记
  9. 题解:[JSOI2004]平衡点 / 吊打XXX
  10. centos7环境搭建命令List