中午考试困够呛。

T1

我想打矩阵快速幂,然后我咕了

T2

打T1了所以又咕了。

T3

每一个黑点更新答案只有两种方式:

  • 更新子树。
  • 更新父链上的兄弟,叔伯,……

于是:

把树拍在$DFS$序上。

更新子树,区间修改。

更新父链,就需要用$DFS$序的拆分,修改两个部分。

#include <iostream>
#include <cstring>
#include <cstdio>
#define N 111111
#define lc(k) (k<<1)
#define rc(k) (k<<1|1)
using namespace std;
struct SR{
int next,t;
}rs[N*2];
int fl[N],cnt=0;
struct XDS{
int l,r;
int dat,lz;
}rt[4*N];
int fir[N],las[N],wi[N];
int dfsxu[2*N];
int dfcnt=0;
int fa[N],pn,qn;
bool is_v[N];
void add(int f,int t){
rs[cnt].t=t;
rs[cnt].next=fl[f];
fl[f]=cnt++;
}
void build(int k,int l,int r){
// cout<<k<<" "<<l<<" "<<r<<endl;
rt[k].l=l,rt[k].r=r;
rt[k].dat=0;
if(l==r)return ;
int mid=(l+r)/2;
build(lc(k),l ,mid);
build(rc(k),mid+1,r );
}
void downlz(int k){
if(rt[k].l!=rt[k].r && rt[k].lz!=0){
int val=rt[k].lz;
rt[lc(k)].lz=max(rt[lc(k)].lz,val);
rt[rc(k)].lz=max(rt[rc(k)].lz,val);
rt[lc(k)].dat=max(rt[lc(k)].dat,val);
rt[rc(k)].dat=max(rt[rc(k)].dat,val);
rt[k].lz=0;
}
}
void change(int k,int l,int r,int v){
if(l>r)return ;
downlz(k);
if(l<=rt[k].l && rt[k].r<=r){
rt[k].lz=v;
rt[k].dat=max(rt[k].dat,v);
return ;
}
int mid=(rt[k].l+rt[k].r)/2;
if(mid>=l)
change(lc(k),l,r,v);
if(mid<r)
change(rc(k),l,r,v);
rt[k].dat=max(rt[lc(k)].dat,rt[rc(k)].dat);
}
int query(int k,int l,int r){
if(l>r)return 0;
int ans=0;
downlz(k);
if(l<=rt[k].l && rt[k].r<=r)
return rt[k].dat;
int mid=(rt[k].l+rt[k].r)/2;
if(mid>=l)
ans=max(ans,query(lc(k),l,r));
if(mid<r)
ans=max(ans,query(rc(k),l,r));
return ans;
}
void dfs(int k,int pre){
dfcnt++;
dfsxu[dfcnt]=k;
fir[k]=dfcnt;
for(int i=fl[k];i!=-1;i=rs[i].next){
int t=rs[i].t;
if(t!=pre){
fa[t]=k;
dfs(t,k);
}
}
dfcnt++;
dfsxu[dfcnt]=k;
las[k]=dfcnt;
}
int main(){
// freopen("lca3.in","r",stdin);\
freopen("1.out","w",stdout);
int a,b;
char st[10];
memset(fl,-1,sizeof fl);
scanf("%d%d",&pn,&qn);
for(int i=1;i<=pn;i++)
scanf("%d",wi+i);
for(int i=1;i<pn;i++){
scanf("%d%d",&a,&b);
add(a,b);
add(b,a);
}
dfs(1,0);
// for(int i=1;i<=pn*2;i++)\
cout<<dfsxu[i]<<" ";\
cout<<endl;
build(1,1,pn*2);
for(int i=1;i<=qn;i++){
scanf("%s%d",st,&a);
if(st[0]=='M'){
change(1,fir[a],las[a],wi[a]);
// cout<<fir[a]<<"="<<las[a]<<endl;
while(fa[a]!=0){
// cout<<"A:"<<a<<" FAA:"<<fa[a]<<" wi:"<<wi[fa[a]]<<endl;
change(1,fir[fa[a]],fir[a]-1,wi[fa[a]]);
// cout<<fir[fa[a]]<<" "<<fir[a]-1<<endl;
change(1,las[a]+1,las[fa[a]],wi[fa[a]]);
// cout<<las[a]+1<<" "<<las[fa[a]]-1<<endl;
if(is_v[a])break;
is_v[a]=1;
a=fa[a];
}
}
else {
int ans=query(1,fir[a],fir[a]);
printf("%d\n",ans==0?-1:ans);
}
}
}

最新文章

  1. Linux零起点之进程管理----c语言编程
  2. 拓展 Android 原生 CountDownTimer 倒计时
  3. CI框架整合yar
  4. win10 用cmake 3.5.2 和 vs 2015 update1 编译 GPU版本(cuda 8.0, cudnn v5 for cuda 8.0)
  5. 用c和c++的方式实现栈
  6. php 用户ip的获取
  7. 【原创】kafka controller源代码分析(一)
  8. guake默认快捷键
  9. .net mvc mssql easyui treegrid 及时 编辑 ,支持拖拽
  10. 遍历Arraylist的方法
  11. Mysql 查询缓存总结
  12. 用redis的scan命令代替keys命令,以及在spring-data-redis中遇到的问题
  13. Scala(三)
  14. mtd-utils交叉编译安装
  15. history.pushState无刷新改变url
  16. 个人作业2——WordCount
  17. JavaSE日常笔记汇总
  18. IE访问历史记录恢复工具pasco
  19. JS的checkbox状态切换dom无变化
  20. ruby 正则表达式Regexp

热门文章

  1. elasticsearch+filebeat+kibana提取多行日志
  2. SQLite加密 wxSqlite3
  3. QtCreator 生成动态库
  4. maven项目引入外部第三方jar包,引入、本地编译、第三方jar一起打到jar中、在linux机器中解决classnotfound(配置classpath),笔记整理。
  5. LUA中的冒号、点和self
  6. 纵览轻量化卷积神经网络:SqueezeNet、MobileNet、ShuffleNet、Xception
  7. 全网最全乌云drops文章下载(epub)
  8. android ListView 获取点击的选项
  9. 跳过爱奇艺优酷vip
  10. eclipse中启动tomcat之后,项目一直重复部署导致内存报警!!!