思路:

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

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. Oracle Study之--Oracle 单实例11.2.0.1.0升级到11.2.0.3.0

    Oracle Study之--Oracle 单实例11.2.0.1.0升级到11.2.0.3.0 系统环境: 操作系统:RedHat EL6(64位) Oracle:    Oracle 11gR2 ...

  2. Windows环境下通过Git来管理自己的Android代码

    前面已经介绍了在Windows下使用git工具来下载Android的源代码,Windows环境下通过Git得到Android源代码,这里记录我使用git工具来管理我自己的代码,git是一种分布式的项目 ...

  3. Devexpress控件使用一:GridControl

    1.控件及列表展示 1).控件 2).构建表格,用于列表展示 3).gridControl绑定数据 4).调用绑定:BindDataSource(InitDt()); 5).展示列表 2.表格的列配置 ...

  4. Hibernate框架学习(一)——入门

    一.框架是什么 1.框架是用来提高开发效率的 2.封装好了一些功能,我们需要使用这些功能时,调用即可,不需要手动实现 3.框架可以理解成一个半成品的项目,只要懂得如何驾驭这些功能即可 二.hibern ...

  5. 【摘录】JDBC Master Slave(JDBC方式的JMS集群)

    JDBC Master Slave First supported in ActiveMQ version 4.1 If you are using pure JDBC and not using t ...

  6. 如何新建一个空的optix工程

    参考链接 1.生成自定义里面添加cuda编译器 2. 修改这几个地方,设定cu文件需要的头文件.输出ptx文件的目录.生成ptx 这样就可以得到ptx了,注意ptx的路径即可 3.添加一些头文件.li ...

  7. JS自定义全局Error

    <script> ///自定义错误 onerror=handleErr; function handleErr(msg,url,l) { var txt=""; txt ...

  8. python学习笔记:第六天

    一.元组(通用格式a=(1,),结束后面加个逗号,不同与数组是中括号,只能是只读的,不能修改,是有序的): 列表之间可以嵌套(列表之间嵌套,嵌套元组,是有序的):a[b[1,2],c[3,4]],输出 ...

  9. ocrsearch的横屏转竖屏的解决方案

    //这是其中解决预览图的一部分(坑了好久的)@Override public void onPreviewFrame(byte[] data, Camera camera) { Size previe ...

  10. Hibernate持久化步骤

      1. 读取并解析配置文件 Configuration config= new Configuration().configure(); 相当于使用DataSource获取连接前读取DataSour ...