BZOJ 3083 树链剖分+倍增+线段树
思路:
先随便选个点 链剖+线段树
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 树链剖分+倍增+线段树的更多相关文章
- HDU3710 Battle over Cities(最小生成树+树链剖分+倍增+线段树)
Battle over Cities Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Othe ...
- bzoj 4034 [HAOI2015] T2(树链剖分,线段树)
4034: [HAOI2015]T2 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1536 Solved: 508[Submit][Status] ...
- bzoj 1036 [ZJOI2008]树的统计Count(树链剖分,线段树)
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 10677 Solved: 4313[Submit ...
- bzoj 3626 [LNOI2014]LCA(离线处理+树链剖分,线段树)
3626: [LNOI2014]LCA Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1272 Solved: 451[Submit][Status ...
- bzoj 2243 [SDOI2011]染色(树链剖分,线段树)
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 4637 Solved: 1726[Submit][Status ...
- 【BZOJ5507】[GXOI/GZOI2019]旧词(树链剖分,线段树)
[BZOJ5507][GXOI/GZOI2019]旧词(树链剖分,线段树) 题面 BZOJ 洛谷 题解 如果\(k=1\)就是链并裸题了... 其实\(k>1\)发现还是可以用类似链并的思想,这 ...
- poj 3237 Tree(树链剖分,线段树)
Tree Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 7268 Accepted: 1969 Description ...
- HDU 4366 Successor(树链剖分+zkw线段树+扫描线)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=4366 [题目大意] 有一个公司,每个员工都有一个上司,所有的人呈树状关系,现在给出每个人的忠诚值和 ...
- 【BZOJ3531】旅行(树链剖分,线段树)
[BZOJ3531]旅行(树链剖分,线段树) 题面 Description S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足 从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教 ...
随机推荐
- Nginx系列(四)--工作原理
上篇文章介绍了Nginx框架的设计之管理进程以及多个工作进程的设计.master进程用来管理通过fork子进程与子进程通信.子进程通过处理进程信号接到master的通信去处理请求. Nginx工作原理 ...
- fancybox关闭弹出窗体parent.$.fancybox.close();
fancybox弹出窗体右上角会自带一个关闭窗体,而且点击遮罩层也会关闭fancybox 有时我们不须要这样进行关闭,隐藏关闭窗体,而且遮罩层不可点击 在弹出窗体页面加一链接进行关闭使用parent. ...
- LeetCode——Copy List with Random Pointer
A linked list is given such that each node contains an additional random pointer which could point t ...
- 小贝_mysql三种子查询
mysql三种子查询 简要: 一.三种子查询 二.三种子查询理解模型 一.mysql 三种子查询 where子查询.from子查询.exists子查询 二.理解模型: 2.1.一个好的模型,便于我们去 ...
- 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 ...
- 12.boost有向图无向图(矩阵法)
#include <iostream> #include <boost/config.hpp> //图 #include <boost/graph/adjacency_m ...
- 从零开始编写一个vue插件
title: 从零开始编写一个vue插件 toc: true date: 2018-12-17 10:54:29 categories: Web tags: vue mathjax 写毕设的时候需要一 ...
- express+模板引擎构建项目时遇到的几个小问题
1.启动项目/调试项目 项目启动用:npm start 由于每次更改路由代码后必须重启服务才可以看效果,所以为了达到热加载的效果我们安装 supervisor:全局安装也可以: npm install ...
- python网页问题
#django-admin不是个命令 添加环境变量 D:\Python36\Scripts #localhost加载失败 命令行 python manage.py runserver 0.0.0.0: ...
- 肆、js的DOM模型
一.网页中的dom模型框架 1.dom中的3中节点:元素节点.文本节点.属性节点 a.元素节点:html中的各种标签就是各个元素节点,元素节点可以包含其他元素,只有html根节点例外. b.文本节点: ...