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条双向道路连接,满足 从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教 ...
随机推荐
- 取消记录tableView选中效果
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [self. ...
- Linux以下的两种文件锁
文件锁是一种文件读写机制.在不论什么特定的时间仅仅同意一个进程訪问一个文件. 利用这样的机制可以使读写单个文件的过程变得更安全. 在这篇文章中.我们将探讨Linux中不同类型的文件锁,并通过演示样例程 ...
- 基于MySQL元数据的Hive的安装和简单測试
引言: Hive是一种强大的数据仓库查询语言,类似SQL,本文将介绍怎样搭建Hive的开发測试环境. 1. 什么是Hive? hive是基于Hadoop的一个数据仓库工具,能够将结构化的数据文件映射为 ...
- html5中调用摄像头拍照
方法: getCamera: 获取摄像头管理对象 对象: Camera: 摄像头对象 CameraOption: JSON对象.调用摄像头的參数 PopPosition: JSON对象,弹出拍照或摄像 ...
- 超便携式截屏录屏软件FastStone Capture
超便携式截屏录屏软件FastStone Capture
- ES task管理
Task Management API The Task Management API is new and should still be considered a beta feature. Th ...
- [jzoj 4528] [GDOI2019模拟2019.3.26] 要换换名字 (最大权闭合子图)
题目链接: https://jzoj.net/senior/#contest/show/2683/0 题目: 题解: 不妨枚举一个点,让两颗树都以这个点为根,求联通块要么点数为$0$,要么包括根(即联 ...
- C#使用tesseract3.02识别验证码模拟登录
一.前言 使用tesseract3.02识别有验证码的网站 安装tesseract3.02 在VS nuget 搜索Tesseract即可. 二.项目结构图 三.项目主要代码 using System ...
- 用js将CheckBox的值存入数据库和将数据库字符串的值转为数组选中CheckBox
Index @{ ViewBag.Title = "测试"; } <script src="~/Scripts/jquery-1.10.2.js"> ...
- swift语言点评一
一.变量定义 1.常量与变量 Use let to make a constant and var to make a variable. 2.类型与推测 However, you don’t alw ...