数据结构(树链剖分,堆):HNOI 2016 network
2215. [HNOI2016]网络
★★★☆ 输入文件:network_tenderRun.in 输出文件:network_tenderRun.out 简单对比
时间限制:2 s 内存限制:128 MB
【题目描述】


【输入格式】

【输出格式】

【样例输入1】
13 23
1 2
1 3
2 4
2 5
3 6
3 7
4 8
4 9
6 10
6 11
7 12
7 13
2 1
0 8 13 3
0 9 12 5
2 9
2 8
2 2
0 10 12 1
2 2
1 3
2 7
2 1
0 9 5 6
2 4
2 5
1 7
0 9 12 4
0 10 5 7
2 1
2 4
2 12
1 2
2 5
2 3
【样例输出1】
-1
3
5
-1
1
-1
1
1
3
6
7
7
4
6
【提示】


这道题是水题。
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
const int maxn=;
int n,Q,cnt,fir[maxn],nxt[maxn<<],to[maxn<<];
void addedge(int a,int b){
nxt[++cnt]=fir[a];fir[a]=cnt;to[cnt]=b;
} struct Data{
int ID,val;
Data(int id=,int V=){
ID=id;val=V;
}
bool operator <(const Data &a)const{
return val<a.val;
}
}; priority_queue<Data>Mx[maxn<<]; int dep[maxn],fa[maxn],sz[maxn],son[maxn];
bool del[maxn]; void DFS(int x){
sz[x]=;
for(int i=fir[x];i;i=nxt[i])
if(to[i]!=fa[x]){
fa[to[i]]=x;
dep[to[i]]=dep[x]+;
DFS(to[i]);
sz[x]+=sz[to[i]];
if(sz[son[x]]<sz[to[i]])
son[x]=to[i];
}
} int tot,ID[maxn],top[maxn]; void DFS(int x,int tp){
ID[x]=++tot;top[x]=tp;
if(son[x])DFS(son[x],tp);
for(int i=fir[x];i;i=nxt[i])
if(to[i]!=fa[x]&&to[i]!=son[x])
DFS(to[i],to[i]);
} void Build(int x,int l,int r){
Mx[x].push(Data(,-));
if(l==r)return;
int mid=(l+r)>>;
Build(x<<,l,mid);
Build(x<<|,mid+,r);
} int Query(int x,int l,int r,int g){
while(del[Mx[x].top().ID])
Mx[x].pop();
if(l==r)
return Mx[x].top().val;
int mid=(l+r)>>;
if(mid>=g)return max(Mx[x].top().val,Query(x<<,l,mid,g));
else return max(Mx[x].top().val,Query(x<<|,mid+,r,g));
} struct Node{
int l,r;
Node(int L=,int R=){
l=L;r=R;
}
bool operator <(const Node &a)const{
return l<a.l;
}
}st[maxn]; void Update(int x,int l,int r,int a,int b,int id,int val){
if(l>=a&&r<=b){
Mx[x].push(Data(id,val));
return;
}
int mid=(l+r)>>;
if(mid>=a)Update(x<<,l,mid,a,b,id,val);
if(mid<b)Update(x<<|,mid+,r,a,b,id,val);
return;
} void Solve(int x,int y,int id,int val){
int tp=;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])
swap(x,y); st[++tp]=Node(ID[top[x]],ID[x]);
x=fa[top[x]];
} if(dep[x]<dep[y])swap(x,y);
st[++tp]=Node(ID[y],ID[x]); sort(st+,st+tp+); int L=;
for(int i=;i<=tp;i++){
if(L<=st[i].l-)
Update(,,n,L,st[i].l-,id,val);
L=st[i].r+;
} if(L<=n)
Update(,,n,L,n,id,val); return;
} int main(){
#ifndef ONLINE_JUDGE
freopen("network_tenderRun.in","r",stdin);
freopen("network_tenderRun.out","w",stdout);
#endif
scanf("%d%d",&n,&Q);
for(int i=,a,b;i<n;i++){
scanf("%d%d",&a,&b);
addedge(a,b);
addedge(b,a);
} DFS();
DFS(,);
Build(,,n); for(int t=,type,a,b,v;t<=Q;t++){
scanf("%d",&type);
if(type==){
scanf("%d%d%d",&a,&b,&v);
Solve(a,b,t,v);
}
else if(type==){
scanf("%d",&a);
del[a]=true;
}
else if(type==){
scanf("%d",&a);
printf("%d\n",Query(,,n,ID[a]));
}
}
return ;
}
5月20日BZOJ加了一组数据,上面的程序MLE了,只能使用手写栈。
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
const int maxn=;
int n,Q,cnt,fir[maxn],nxt[maxn<<],to[maxn<<];
void addedge(int a,int b){
nxt[++cnt]=fir[a];fir[a]=cnt;to[cnt]=b;
}
priority_queue<int>Mx[maxn<<],del[maxn<<]; int dep[maxn],fa[maxn],sz[maxn],son[maxn],vis[maxn];
int ID[maxn],top[maxn],tot,U[maxn<<],V[maxn<<],val[maxn<<];
int stack[maxn],head; void DFS(int x){
stack[++head]=x;
while(head){
x=stack[head];
if(vis[x]){
if(fa[x]){
sz[fa[x]]+=sz[x];
if(sz[son[fa[x]]]<sz[x])
son[fa[x]]=x;
}
head--;
continue;
}
vis[x]=true;sz[x]=;
for(int i=fir[x];i;i=nxt[i])
if(to[i]!=fa[x]){
fa[to[i]]=x;
dep[to[i]]=dep[x]+;
stack[++head]=to[i];
}
}
} void DFS(int x,int tp){
top[x]=tp;
stack[++head]=x;
while(head){
x=stack[head];
if(vis[x]){
head--;
continue;
}
vis[x]=true;
ID[x]=++tot;
for(int i=fir[x];i;i=nxt[i])
if(to[i]!=fa[x]&&to[i]!=son[x]){
stack[++head]=to[i];
top[to[i]]=to[i];
}
if(son[x]){
stack[++head]=son[x];
top[son[x]]=top[x];
}
}
} int Query(int x,int l,int r,int g){
while(!del[x].empty()&&del[x].top()==Mx[x].top())del[x].pop(),Mx[x].pop();
if(l==r)
return Mx[x].empty()?-:Mx[x].top();
int mid=(l+r)>>,ret=Mx[x].empty()?-:Mx[x].top();
if(mid>=g)return max(ret,Query(x<<,l,mid,g));
else return max(ret,Query(x<<|,mid+,r,g));
} struct Node{
int l,r;
Node(int L=,int R=){
l=L;r=R;
}
bool operator <(const Node &a)const{
return l<a.l;
}
}st[maxn<<]; void Update(int x,int l,int r,int a,int b,int val,int on){
if(l>=a&&r<=b){
if(on)
Mx[x].push(val);
else
del[x].push(val);
return;
}
int mid=(l+r)>>;
if(mid>=a)Update(x<<,l,mid,a,b,val,on);
if(mid<b)Update(x<<|,mid+,r,a,b,val,on);
return;
} void Solve(int x,int y,int val,int on){
int tp=;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])
swap(x,y); st[++tp]=Node(ID[top[x]],ID[x]);
x=fa[top[x]];
} if(dep[x]<dep[y])swap(x,y);
st[++tp]=Node(ID[y],ID[x]); sort(st+,st+tp+); int L=;
for(int i=;i<=tp;i++){
if(L<=st[i].l-)
Update(,,n,L,st[i].l-,val,on);
L=st[i].r+;
} if(L<=n)
Update(,,n,L,n,val,on); return;
} int main(){
#ifndef ONLINE_JUDGE
//freopen("network_tenderRun.in","r",stdin);
//freopen("network_tenderRun.out","w",stdout);
#endif
scanf("%d%d",&n,&Q);
for(int i=,a,b;i<n;i++){
scanf("%d%d",&a,&b);
addedge(a,b);
addedge(b,a);
} DFS();
memset(vis,,sizeof(vis));
DFS(,); for(int t=,type,a;t<=Q;t++){
scanf("%d",&type);
if(type==){
scanf("%d%d%d",&U[t],&V[t],&val[t]);
Solve(U[t],V[t],val[t],);
}
else if(type==){
scanf("%d",&a);
Solve(U[a],V[a],val[a],);
}
else if(type==){
scanf("%d",&a);
printf("%d\n",Query(,,n,ID[a]));
}
}
return ;
}
如下:
数据结构(树链剖分,堆):HNOI 2016 network的更多相关文章
- BZOJ4538:[HNOI2016]网络(树链剖分,堆)
Description 一个简单的网络系统可以被描述成一棵无根树.每个节点为一个服务器.连接服务器与服务器的数据线则看做 一条树边.两个服务器进行数据的交互时,数据会经过连接这两个服务器的路径上的所有 ...
- 【BZOJ1146】【树链剖分+平衡树】网络管理Network
Description M 公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工作,公司搭建了一个连接整个公司的通 信网络.该网络的结构由N个 ...
- luoguP3250 [HNOI2016]网络 树链剖分 + 堆
机房某大佬告诉我,一条链在全局线段树中的区间最多有$log$段 因此同样的,代表不在这条链上的区间同样只有$log$段 对这$log$段区间进行维护即可 为了能够删除,在线段树的每个节点暴力维护一个堆 ...
- 数据结构(树链剖分):BZOJ 4034: [HAOI2015]T2
Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中 ...
- 数据结构--树链剖分准备之LCA
有关LCA的模板题 传送门 题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询问的个数和 ...
- 数据结构(树链剖分):COGS 2109. [NOIP2015] 运输计划
2109. [NOIP2015] 运输计划 ★★★ 输入文件:transport.in 输出文件:transport.out 简单对比时间限制:1 s 内存限制:256 MB [题目描 ...
- 数据结构(并查集||树链剖分):HEOI 2016 tree
[注意事项] 为了体现增强版,题目限制和数据范围有所增强: 时间限制:1.5s 内存限制:128MB 对于15% 的数据,1<=N,Q<=1000. 对于35% 的数据,1<=N,Q ...
- BZOJ 1146: [CTSC2008]网络管理Network 树链剖分+线段树+平衡树
1146: [CTSC2008]网络管理Network Time Limit: 50 Sec Memory Limit: 162 MBSubmit: 870 Solved: 299[Submit] ...
- BZOJ 1146: [CTSC2008]网络管理Network( 树链剖分 + 树状数组套主席树 )
树链剖分完就成了一道主席树裸题了, 每次树链剖分找出相应区间然后用BIT+(可持久化)权值线段树就可以完成计数. 但是空间问题很严重....在修改时不必要的就不要新建, 直接修改原来的..详见代码. ...
随机推荐
- 怎样写好一份IT技术岗位的简历
10月是校园招聘的旺季,很多应届毕业生都忙碌起来了,从CSDN笔试-面试文章的火热程度,从我收到的简历就看得出来. 我很久没有参与笔试和面试了,所以只能从“简历”来阐述下我的看法. 截至目前,已经帮8 ...
- 处理ASP.NET 请求(IIS)(2)
ASP.NET与IIS是紧密联系的,由于IIS6.0与IIS7.0的工作方式的不同,导致ASP.NET的工作原理也发生了相应的变化. IIS6(IIS7的经典模式)与IIS7的集成模式的不同 IIS6 ...
- 给Sublime Text2安装轻量级代码提示插件:SublimeCodeIntel
步骤: 1.下载SublimeCodeIntel(地址https://github.com/SublimeCodeIntel/SublimeCodeIntel): 2.将下载的压缩包解压,并放置在Pa ...
- 在eclipse中将java导出为可执行文件.
Ref: http://java.chinaitlab.com/Eclipse/812775.html and http://www.javavids.com/video/how-to-create- ...
- Deep Learning 学习随记(八)CNN(Convolutional neural network)理解
前面Andrew Ng的讲义基本看完了.Andrew讲的真是通俗易懂,只是不过瘾啊,讲的太少了.趁着看完那章convolution and pooling, 自己又去翻了翻CNN的相关东西. 当时看讲 ...
- IOS 多线程,线程同步的三种方式
本文主要是讲述 IOS 多线程,线程同步的三种方式,更多IOS技术知识,请登陆疯狂软件教育官网. 一般情况下我们使用线程,在多个线程共同访问同一块资源.为保护线程资源的安全和线程访问的正确性. 在IO ...
- java项目测试log4j
.literal { background-color: #f2f2f2; border: 1px solid #cccccc; padding: 1px 3px 0; white-space: no ...
- (java)从零开始之--装饰者设计模式
装饰者设计模式:简单定义:增强一个类的功能,而且还可以让这些装饰类互相装饰. 应用场景:当要在某个功能的基础上扩充功能,并且扩充的功能具有大量排列组合,通过继承关系会衍生出大量子类,这时候用装饰者模式 ...
- asp.net尽量不在js里写<%%>
asp.net尽量不在js里写<%%> eg: <script type="text/javascript"> var rootsid="&quo ...
- VC++读取资源中文件
//查找目标资源 HRSRC hResource = FindResource(GetModuleHandle(NULL), MAKEINTRESOURCE(IDR_MAINPROG), TEXT(& ...