思路:

先随便选个点 链剖+线段树

1操作 就直接改root变量的值

2操作 线段树上改

3操作

分成三种情况

1.new root = xx 整个子树的min就是ans

2. lca(new root,xx) !=xx query 一下 当前的标号 和当前的标号+size(链剖不就是个特殊的dfs序嘛)

3. lca(new root,xx) =xx 找一下root在xx的哪个子树里 这个子树的补集就是解了

好多题解写得是有问题的

他们找root在xx的哪个子树里 这个操作是暴力找的 会被菊花图卡

(所以我就又写了个倍增)

后附 对拍程序 (这玩意儿一遍AC真是幻想 啊……)

//By SiriusRen33333333333333
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 222222
int n,m,op,xx,yy,zz,v[N],next[N],first[N],tot,wei[N],tree[N*8],lazy[N*8];
int size[N],son[N],fa[N],deep[N],top[N],change[N],cnt,root,f[N][20],rev[N];
void add(int x,int y){v[tot]=y,next[tot]=first[x],first[x]=tot++;}
void dfs(int x){
size[x]=1;
for(int i=1;i<=19;i++)if((1<<i)<=deep[x])f[x][i]=f[f[x][i-1]][i-1];else break;
for(int i=first[x];~i;i=next[i])if(v[i]!=fa[x]){
fa[v[i]]=f[v[i]][0]=x,deep[v[i]]=deep[x]+1,dfs(v[i]);
size[x]+=size[v[i]];
if(size[son[x]]<size[v[i]])son[x]=v[i];
}
}
void dfs2(int x,int tp){
change[x]=++cnt,rev[cnt]=x,top[x]=tp;
if(son[x])dfs2(son[x],tp);
for(int i=first[x];~i;i=next[i])
if(v[i]!=fa[x]&&v[i]!=son[x])
dfs2(v[i],v[i]);
}
void push_down(int pos){lazy[pos<<1]=lazy[pos<<1|1]=tree[pos<<1]=tree[pos<<1|1]=lazy[pos];lazy[pos]=-1;}
void build(int l,int r,int pos){
if(l==r){tree[pos]=wei[rev[l]];return;}
int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
build(l,mid,lson),build(mid+1,r,rson);
tree[pos]=min(tree[lson],tree[rson]);
}
void insert(int l,int r,int pos,int L,int R,int val){
if(l>=L&&r<=R){tree[pos]=lazy[pos]=val;return;}
if(~lazy[pos])push_down(pos);
int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
if(mid<L)insert(mid+1,r,rson,L,R,val);
else if(mid>=R)insert(l,mid,lson,L,R,val);
else insert(l,mid,lson,L,R,val),insert(mid+1,r,rson,L,R,val);
tree[pos]=min(tree[lson],tree[rson]);
}
int query(int l,int r,int pos,int L,int R){
if(l>=L&&r<=R)return tree[pos];
if(~lazy[pos])push_down(pos);
int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
if(mid<L)return query(mid+1,r,rson,L,R);
else if(mid>=R)return query(l,mid,lson,L,R);
else return min(query(l,mid,lson,L,R),query(mid+1,r,rson,L,R));
}
void Change(int x,int y,int val){
int fx=top[x],fy=top[y];
while(fx!=fy){
if(deep[fx]<deep[fy])swap(x,y),swap(fx,fy);
insert(1,n,1,change[fx],change[x],val);
x=fa[fx],fx=top[x];
}if(deep[x]>deep[y])swap(x,y);
insert(1,n,1,change[x],change[y],val);
}
int LCA(int x,int y){
int fx=top[x],fy=top[y];
while(fx!=fy){
if(deep[fx]<deep[fy])swap(x,y),swap(fx,fy);
x=fa[fx],fx=top[x];
}return deep[x]>deep[y]?y:x;
}
int main(){
memset(first,-1,sizeof(first)),memset(lazy,-1,sizeof(lazy));
scanf("%d%d",&n,&m);
for(int i=1;i<n;i++)scanf("%d%d",&xx,&yy),add(xx,yy),add(yy,xx);
for(int i=1;i<=n;i++)scanf("%d",&wei[i]);
dfs(1),dfs2(1,1),build(1,n,1);
scanf("%d",&root);
for(int i=1;i<=m;i++){
scanf("%d%d",&op,&xx);
if(op==1)root=xx;
else if(op==2)scanf("%d%d",&yy,&zz),Change(xx,yy,zz);
else{
if(root==xx){printf("%d\n",tree[1]);continue;}
int lca=LCA(xx,root);
if(xx!=lca)printf("%d\n",query(1,n,1,change[xx],change[xx]+size[xx]-1));
else{
int tmp=deep[root]-deep[xx]-1,ans=0x3f3f3f3f;yy=root;
for(int i=0;i<=19;i++)if((1<<i)&tmp)yy=f[yy][i];
if(change[yy]>1)ans=query(1,n,1,1,change[yy]-1);
if(change[yy]+size[yy]<=n)ans=min(ans,query(1,n,1,change[yy]+size[yy],n));
printf("%d\n",ans);
}
}
}
}

maker

//By SiriusRen
#include <ctime>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n=100000,m=100000,seed;
int main(){
freopen("seed.txt","r",stdin);
scanf("%d",&seed);
srand(seed+time(0));rand();rand();rand();rand();rand();rand();rand();rand();
freopen("seed.txt","w",stdout);
printf("%d\n",seed);
freopen("in.txt","w",stdout);
printf("%d %d\n",n,m);
for(int i=2;i<=n;i++)printf("%d %d\n",rand()%(i-1)+1,i);
for(int i=1;i<=n;i++)printf("%d ",rand()+1);
printf("\n%d\n",rand()%n+1);
for(int i=1;i<=m;i++){
int temp=rand();
if(temp%3==0)printf("1 %d\n",rand()%n+1);
else if(temp%3==1)printf("2 %d %d %d\n",rand()%n+1,rand()%n+1,rand()+1);
else printf("3 %d\n",rand()%n+1);
}
}

对拍:

//By SiriusRen
#include <ctime>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int cases;
int main(){
while(1){
printf("Case %d now~~~\n",++cases);
system("mk.exe");
int lasttime=clock();
system("mine.exe<in.txt>out1.txt");
printf("mine time=%ld\n",clock()-lasttime);
lasttime=clock();
system("sol.exe<in.txt>out2.txt");
printf("solution time=%ld\n",clock()-lasttime);
lasttime=clock();
if(system("fc out1.txt out2.txt")){
puts("Wrong Answer~~~");
while(1);
}
}
}

BZOJ 3083 树链剖分+倍增+线段树的更多相关文章

  1. HDU3710 Battle over Cities(最小生成树+树链剖分+倍增+线段树)

    Battle over Cities Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Othe ...

  2. bzoj 4034 [HAOI2015] T2(树链剖分,线段树)

    4034: [HAOI2015]T2 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1536  Solved: 508[Submit][Status] ...

  3. bzoj 1036 [ZJOI2008]树的统计Count(树链剖分,线段树)

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 10677  Solved: 4313[Submit ...

  4. bzoj 3626 [LNOI2014]LCA(离线处理+树链剖分,线段树)

    3626: [LNOI2014]LCA Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1272  Solved: 451[Submit][Status ...

  5. bzoj 2243 [SDOI2011]染色(树链剖分,线段树)

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 4637  Solved: 1726[Submit][Status ...

  6. 【BZOJ5507】[GXOI/GZOI2019]旧词(树链剖分,线段树)

    [BZOJ5507][GXOI/GZOI2019]旧词(树链剖分,线段树) 题面 BZOJ 洛谷 题解 如果\(k=1\)就是链并裸题了... 其实\(k>1\)发现还是可以用类似链并的思想,这 ...

  7. poj 3237 Tree(树链剖分,线段树)

    Tree Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 7268   Accepted: 1969 Description ...

  8. HDU 4366 Successor(树链剖分+zkw线段树+扫描线)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=4366 [题目大意] 有一个公司,每个员工都有一个上司,所有的人呈树状关系,现在给出每个人的忠诚值和 ...

  9. 【BZOJ3531】旅行(树链剖分,线段树)

    [BZOJ3531]旅行(树链剖分,线段树) 题面 Description S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足 从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教 ...

随机推荐

  1. Nginx系列(四)--工作原理

    上篇文章介绍了Nginx框架的设计之管理进程以及多个工作进程的设计.master进程用来管理通过fork子进程与子进程通信.子进程通过处理进程信号接到master的通信去处理请求. Nginx工作原理 ...

  2. fancybox关闭弹出窗体parent.$.fancybox.close();

    fancybox弹出窗体右上角会自带一个关闭窗体,而且点击遮罩层也会关闭fancybox 有时我们不须要这样进行关闭,隐藏关闭窗体,而且遮罩层不可点击 在弹出窗体页面加一链接进行关闭使用parent. ...

  3. LeetCode——Copy List with Random Pointer

    A linked list is given such that each node contains an additional random pointer which could point t ...

  4. 小贝_mysql三种子查询

    mysql三种子查询 简要: 一.三种子查询 二.三种子查询理解模型 一.mysql 三种子查询 where子查询.from子查询.exists子查询 二.理解模型: 2.1.一个好的模型,便于我们去 ...

  5. Defining and using constants from PySide in QML

    Defining and using constants from PySide in QML This PySide tutorial shows you how to define constan ...

  6. 12.boost有向图无向图(矩阵法)

    #include <iostream> #include <boost/config.hpp> //图 #include <boost/graph/adjacency_m ...

  7. 从零开始编写一个vue插件

    title: 从零开始编写一个vue插件 toc: true date: 2018-12-17 10:54:29 categories: Web tags: vue mathjax 写毕设的时候需要一 ...

  8. express+模板引擎构建项目时遇到的几个小问题

    1.启动项目/调试项目 项目启动用:npm start 由于每次更改路由代码后必须重启服务才可以看效果,所以为了达到热加载的效果我们安装 supervisor:全局安装也可以: npm install ...

  9. python网页问题

    #django-admin不是个命令 添加环境变量 D:\Python36\Scripts #localhost加载失败 命令行 python manage.py runserver 0.0.0.0: ...

  10. 肆、js的DOM模型

    一.网页中的dom模型框架 1.dom中的3中节点:元素节点.文本节点.属性节点 a.元素节点:html中的各种标签就是各个元素节点,元素节点可以包含其他元素,只有html根节点例外. b.文本节点: ...