LCT

QTree也行吧。
思路巧妙,速度颠覆人们对LCT的常识。
发现set.find找不到会返回end(),然后你就把他给删了,这会导致在之后的插入时爆炸。
边权下放点权,upd时要小心。
和其他的比起好短啊。

#include<bits/stdc++.h>
#define maxn 100005
#define inf 0x3f3f3f3f
using namespace std;int q;
int n;
int info[maxn],Prev[maxn<<1],to[maxn<<1],cst[maxn<<1],cnt_e;
void Node(int u,int v,int c){ Prev[++cnt_e]=info[u],info[u]=cnt_e,to[cnt_e]=v,cst[cnt_e]=c; }
multiset<int>chain[maxn],path[maxn];
void checkmax(int &a,int b){a = max(a,b);
}
int Max(multiset<int>&s){ return !s.empty() ? *s.rbegin() : -inf; }
int sMax(multiset<int>&s){ return s.size()>1 ? *(++s.rbegin()) : -inf; }
namespace LCT{int ch[maxn][2],fa[maxn],val[maxn],lmx[maxn],rmx[maxn],sum[maxn],mx[maxn],w[maxn];#define il inline #define pa fa[x]il int inr(int x){ return ch[pa][1]==x; }il int isr(int x){ return ch[pa][0]!=x&&ch[pa][1]!=x; }il void upd(int x){int xsl = max(w[x],Max(chain[x]));//printf("%d %d\n",x,xsl);lmx[x]=lmx[ch[x][0]],rmx[x]=rmx[ch[x][1]];//printf("%d %d\n",ch[x][0],lmx[ch[x][0]]);checkmax(lmx[x],sum[ch[x][0]]+val[x]+max(xsl,lmx[ch[x][1]]));//checkmax(rmx[x],rmx[ch[x][1]]);checkmax(rmx[x],sum[ch[x][1]]+max(xsl,rmx[ch[x][0]]+val[x]));sum[x] = sum[ch[x][0]] + sum[ch[x][1]] + val[x];mx[x] = -inf;checkmax(mx[x],lmx[ch[x][1]]+max(xsl,rmx[ch[x][0]]+val[x]));checkmax(mx[x],rmx[ch[x][0]]+max(xsl,lmx[ch[x][1]])+val[x]);checkmax(mx[x],max(mx[ch[x][0]],mx[ch[x][1]]));checkmax(mx[x],Max(path[x]));checkmax(mx[x],Max(chain[x])+sMax(chain[x]));if(w[x] == 0) checkmax(mx[x],max(0,Max(chain[x])));}il void rot(int x){int y = fa[x] , z = fa[y] , c = inr(x);if(!isr(y)) ch[z][inr(y)] = x;(ch[y][c]=ch[x][!c]) && (fa[ch[y][c]]=y);fa[fa[ch[x][!c]=y]=x]=z;upd(y);}il void splay(int x){for(;!isr(x);rot(x))if(!isr(pa)) rot(inr(pa)==inr(x)?pa:x);upd(x);}il int access(int x,int y=0){for(;x;x=fa[y=x]){ splay(x);if(ch[x][1]) path[x].insert(mx[ch[x][1]]),chain[x].insert(lmx[ch[x][1]]);if(y){/*if(path[x].find(mx[y]) == path[x].end()){printf("%d %d %d\n",x,y,mx[y]);puts("1");}if(chain[x].find(lmx[y]) == chain[x].end()) puts("2");*/path[x].erase(path[x].find(mx[y])),chain[x].erase(chain[x].find(lmx[y]));}ch[x][1]=y,upd(x);}return y;}
}
using namespace LCT;
void dfs(int now,int ff){LCT::fa[now] = ff;for(int i=info[now];i;i=Prev[i])if(to[i]!=ff){LCT::val[to[i]] = cst[i] , LCT::sum[to[i]] = cst[i];dfs(to[i],now);//if(now == 38339 && to[i] == 13462)//    printf("@#$%d\n",mx[to[i]]);chain[now].insert(LCT::lmx[to[i]]);path[now].insert(LCT::mx[to[i]]);}LCT::upd(now);
}int main(){//  freopen("1.in","r",stdin);scanf("%d",&n);for(int i=1,u,v,W;i<n;i++){scanf("%d%d%d",&u,&v,&W);Node(u,v,W),Node(v,u,W);}for(int i=0;i<=n;i++)LCT::mx[i]=LCT::lmx[i]=LCT::rmx[i]=-inf;dfs(1,0);int ans = mx[1];scanf("%d",&q);char s[2];for(int x;q--;){scanf("%s",s);if(s[0] == 'C'){scanf("%d",&x);//printf("@%d\n",x);access(x),splay(x);//printf("@%d\n",x);w[x] = (w[x] ? 0 : -inf);//printf("@%d\n",x);upd(x);ans = mx[x];//printf("@%d\n",x);}elseans>=0?printf("%d\n",ans):puts("They have disappeared.");}
}

贴一份精简版100行的LCT

#include<bits/stdc++.h>
#define maxn 100005
#define LL long long
#define inf 0x3f3f3f3f
using namespace std;int n;
int info[maxn],Prev[maxn<<1],to[maxn<<1],cst[maxn<<1],cnt_e;
void Node(int u,int v,int c){ Prev[++cnt_e]=info[u],info[u]=cnt_e,to[cnt_e]=v,cst[cnt_e]=c; }
multiset<int>path[maxn],chain[maxn];
int Max(multiset<int>&s){ return s.empty()?-inf:*s.rbegin(); }
int sMax(multiset<int>&s){ return s.size()<=1?-inf:*++s.rbegin(); }namespace LCT{int ch[maxn][2],fa[maxn],val[maxn],lm[maxn],rm[maxn],mx[maxn],w[maxn],sum[maxn];#define il inline #define pa fa[x]il int inr(int x){ return ch[pa][1]==x; }il int isr(int x){ return ch[pa][0]!=x && ch[pa][1]!=x; }il void upd(int x){int im = max(w[x],Max(chain[x]));int Um = max(im,rm[ch[x][0]]+val[x]) , Dm = max(im,lm[ch[x][1]])+val[x];lm[x] = max(lm[ch[x][0]],Dm+sum[ch[x][0]]);rm[x] = max(rm[ch[x][1]],Um+sum[ch[x][1]]);mx[x] = max(max(rm[ch[x][0]]+Dm,lm[ch[x][1]]+Um),max(max(Max(path[x]),Max(chain[x])+sMax(chain[x])),max(mx[ch[x][0]],mx[ch[x][1]])));if(w[x]==0) mx[x] = max(mx[x] , max(Max(chain[x]),0));sum[x] = sum[ch[x][0]] + sum[ch[x][1]] + val[x];}il void rot(int x){int y = fa[x] , z = fa[y] , c = inr(x);if(!isr(y)) ch[z][inr(y)] = x;(ch[y][c]=ch[x][!c])&&(fa[ch[y][c]]=y);fa[fa[ch[x][!c]=y]=x]=z;upd(y);}il void splay(int x){for(;!isr(x);rot(x))if(!isr(pa)) rot(inr(pa)==inr(x)?pa:x);upd(x);}il int access(int x,int y=0){for(;x;x=fa[y=x]){splay(x);if(ch[x][1]) path[x].insert(mx[ch[x][1]]),chain[x].insert(lm[ch[x][1]]);if(y) path[x].erase(path[x].find(mx[y])),chain[x].erase(chain[x].find(lm[y]));ch[x][1] = y , upd(x);}return y;}
}
using namespace LCT;
void dfs(int now,int ff){fa[now] = ff; for(int i=info[now];i;i=Prev[i])if(to[i]!=ff){val[to[i]] = sum[to[i]] = cst[i];dfs(to[i],now);path[now].insert(mx[to[i]]),chain[now].insert(lm[to[i]]);}upd(now);
}char cb[1<<15],*cs=cb,*ct=cb;
#define getc() (cs==ct&&(ct=(cs=cb)+fread(cb,1,1<<15,stdin),cs==ct)?0:*cs++)
void read(int &res){char ch;bool f = 0;for(;!isdigit(ch=getc());) if(ch=='-') f=1;for(res=ch-'0';isdigit(ch=getc());res=res*10+ch-'0');(f) && (res = -res);
}int main(){read(n);for(int i=0;i<=n;i++) lm[i]=rm[i]=mx[i]=-inf;for(int i=1,u,v,c;i<n;i++){read(u),read(v),read(c);Node(u,v,c),Node(v,u,c);}dfs(1,0);int ans = mx[1];int Q;read(Q);for(char s[2];Q--;){for(;!isalpha(s[0]=getc()););if(s[0]=='C'){int x;read(x);access(x),splay(x);w[x]=(w[x]?0:-inf);upd(x),ans=mx[x];}else ans>=0?printf("%d\n",ans):puts("They have disappeared.");}
}

树链剖分
括号序列(貌似不能在有边权的情况下做)
动态点分治
线段树维护区间直径(貌似不能在有边权的情况下做)
有谁写个动态边分治,我就加上去。

此题的男人六解。
有时间都打一遍。

[ZJOI2007]Hide 捉迷藏(数据结构)相关推荐

  1. [ZJOI2007]Hide 捉迷藏

    [ZJOI2007]Hide 捉迷藏 小岛的博客 黄学长的博客 NOI08 冬令营论文 <数据结构的提炼与压缩> 这个问题竟然还能用线段树做,拿小本本记下来. 转载于:https://ww ...

  2. 【BZOJ 1095】 1095: [ZJOI2007]Hide 捉迷藏 (括号序列+线段树)

    1095: [ZJOI2007]Hide 捉迷藏 Description 捉迷藏 Jiajia和Wind是一对恩爱的夫妻,并且他们有很多孩子.某天,Jiajia.Wind和孩子们决定在家里玩 捉迷藏游 ...

  3. BZOJ1095 ZJOI2007 Hide 捉迷藏

    BZOJ1095 ZJOI2007 Hide 捉迷藏 动态树分治+堆 动态点分治 posted on 2016-06-25 11:35  wjyi 阅读( ...) 评论( ...) 编辑 收藏 转载 ...

  4. bzoj 1095: [ZJOI2007]Hide 捉迷藏

    Description 捉迷藏 Jiajia和Wind是一对恩爱的夫妻,并且他们有很多孩子.某天,Jiajia.Wind和孩子们决定在家里玩 捉迷藏游戏.他们的家很大且构造很奇特,由N个屋子和N-1条 ...

  5. 「BZOJ1095」[ZJOI2007] Hide 捉迷藏

    题目描述 Jiajia和Wind是一对恩爱的夫妻,并且他们有很多孩子.某天,Jiajia.Wind和孩子们决定在家里玩捉迷藏游戏.他们的家很大且构造很奇特,由N个屋子和N-1条双向走廊组成,这N-1条 ...

  6. BZOJ1095: [ZJOI2007]Hide 捉迷藏(动态点分治)

    Description 捉迷藏 Jiajia和Wind是一对恩爱的夫妻,并且他们有很多孩子.某天,Jiajia.Wind和孩子们决定在家里玩 捉迷藏游戏.他们的家很大且构造很奇特,由N个屋子和N-1条 ...

  7. bzoj1095: [ZJOI2007]Hide 捉迷藏

    题目链接 bzoj1095 题意 Description 捉迷藏 Jiajia和Wind是一对恩爱的夫妻,并且他们有很多孩子.某天,Jiajia.Wind和孩子们决定在家里玩捉迷藏游戏.他们的家很大且 ...

  8. bzoj1095: [ZJOI2007]Hide 捉迷藏 线段树维护括号序列 点分治 链分治

    这题真是十分难写啊 不管是点分治还是括号序列都有一堆细节.. 点分治:时空复杂度$O(n\log^2n)$,常数巨大 主要就是3个堆的初始状态 C堆:每个节点一个,为子树中的点到它父亲的距离的堆. B ...

  9. BZOJ1095 [ZJOI2007]Hide 捉迷藏 【动态点分治 + 堆】

    题目链接 BZOJ1095 题解 传说中的动态点分治,一直不敢碰 今日一会,感觉其实并不艰涩难懂 考虑没有修改,如果不用树形dp的话,就得点分治 对于每个重心,我们会考虑其分治的子树内所有点到它的距离 ...

最新文章

  1. 新人python2和python3的区别_未明学院:Python2与Python3的主要区别
  2. WIN7中 HttpListener 拒绝访问 异常解决 C#
  3. git 代码回退_「Vue 入门系列」第三期,适合新手入门的 Git 使用教程
  4. sqlserver 日常检查脚本
  5. android matrix 缩放,android – 如何获取任意矩阵的缩放值?
  6. tinypng upload一键压缩上传工具
  7. 在集设网欣赏灵感作品合集,感受字体之美
  8. 给我一个及时的问候——XMPP
  9. 9. JEB 1.5插件编写一
  10. apply_async进程不执行_[粉丝问答6]子进程进程的父进程关系
  11. MyEclipse 启动报错:‘Building workspace‘ has encountered a problem解决方法
  12. 系统学习机器学习之神经网络(十) --BAM网络
  13. 搭建MHA时 yum 安装perl模块提示 baseurl 错误
  14. 多步骤查询的解决方案
  15. linux编辑复制多行命令,linux下文本编辑器vim的使用,复制-粘贴-替换-行号-撤销-多文件操作...
  16. Linux CentOS 7 Apache Tomcat 7 安装与配置
  17. python下载电影_Python3.x+迅雷x 自动下载高分电影的实现方法
  18. R语言中常用的生物多样性指数的计算(Alpha,Beta,Gamma,功能多样性,系统发育多样性)
  19. 图论中的0x3f和memset使用注意事项(较详细)
  20. GIS-空间分析(4)

热门文章

  1. Linux读取串口数据
  2. Vue组件封装 ——button组件
  3. ANSYS SIWave SI仿真
  4. 直面OA选型八大误区
  5. windows下app爬虫环境搭建:python + fiddler + Appium + 夜神模拟器
  6. IoGetDeviceProperty 例程
  7. 使用nmcli添加静态/DHCP配置
  8. 【毕设进行时-工业大数据,数据挖掘】对数据库的稍大规模的读写
  9. Mysql错误:Table 'xxx'is marked as crashed and should be repaired
  10. 服务器u盘安装系统读条蓝屏,利用U极速u盘启动盘装win7系统后出现蓝屏现象原因及解决办法...