【BZOJ 1146】【CTSC 2008】网络管理network
一句话题意,树链上带改动区间第k大
感觉能够dfs+主席树O(nlog2n)过掉,但我不会写= =
于是写的线段树套平衡树+链剖+二分(改动O(nlog3n),查询O(nlog4n)慢了好多啊QAQ)
这里简介一下区间第K大做法。对于每一个线段树所”管辖“的范围,建一棵相应范围内的平衡树(我用的Treap);改动时,改动每一个包括被改动节点的线段树节点所相应的Treap。查询时。二分
答案。统计每一个区间内比当前答案小的数就可以(为了保证是序列里的数。我们能够二分答案在原序列中排名)
PS:这题真的是第K大,不是排名第K的,被坑WA了一次= =
code:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define mid (l+r)/2
#define lch i<<1,l,mid
#define rch i<<1|1,mid+1,r
using namespace std;
struct treap_node{
treap_node *left,*right;
int val,fix,size,wgt;
treap_node(int val): val(val) {size=1; wgt=1; left=right=NULL; fix=rand();}
int lsize()
{if (left) return left->size; else return 0;}
int rsize()
{if (right) return right->size; else return 0;}
void Maintain()
{size=wgt; size+=lsize()+rsize();}
};
treap_node *seg[320001];
int f[80001],plc[80001];
int point[80001],next[200001];
struct hp{
int u,v;
}ai[200001];
struct hq{
int dep,fat,top,size,wson;
}tree[80001];
int n,a[80001],ans,m,totw,e=0;
void tlr(treap_node *&a)
{
treap_node *b=a->right;
a->right=b->left; b->left=a;
a->Maintain(); b->Maintain(); a=b;
}
void trr(treap_node *&a)
{
treap_node *b=a->left;
a->left=b->right; b->right=a;
a->Maintain(); b->Maintain(); a=b;
}
void add(int u,int v)
{
e++; ai[e].u=u; ai[e].v=v; next[e]=point[u]; point[u]=e;
e++; ai[e].v=u; ai[e].v=u; next[e]=point[v]; point[v]=e;
}
void insert(treap_node *&p,int value)
{
if (!p)
p=new treap_node(value);
else
{
if (value==p->val)
p->wgt++;
if (value<p->val)
{
insert(p->left,value);
if (p->left->fix<p->fix)
trr(p);
}
if (value>p->val)
{
insert(p->right,value);
if (p->right->fix<p->fix)
tlr(p);
}
}
p->Maintain();
}
void make_node(int i,int l,int r)
{
int j;
for (j=l;j<=r;++j)
insert(seg[i],a[f[j]]);
}
void build(int i,int l,int r)
{
make_node(i,l,r);
if (l==r) return;
build(lch); build(rch);
}
void build_tree(int now,int last,int depth)
{
int i;
tree[now].fat=last;
tree[now].dep=depth;
tree[now].size=1;
tree[now].wson=0;
for (i=point[now];i;i=next[i])
if (ai[i].v!=last)
{
build_tree(ai[i].v,now,depth+1);
tree[now].size+=tree[ai[i].v].size;
if (tree[ai[i].v].size>tree[tree[now].wson].size)
tree[now].wson=ai[i].v;
}
}
void build_seg(int now,int tp)
{
int i;
tree[now].top=tp;
plc[now]=++totw; f[totw]=now;
if (tree[now].wson!=0)
build_seg(tree[now].wson,tp);
for (i=point[now];i;i=next[i])
if (ai[i].v!=tree[now].wson&&ai[i].v!=tree[now].fat)
build_seg(ai[i].v,ai[i].v);
}
void del(treap_node *&p,int val)
{
if (val==p->val)
{
if (p->wgt==1)
{
if (!p->left||!p->right)
{
if (!p->left) p=p->right;
else p=p->left;
}
else
{
if (p->left->fix<p->right->fix)
{trr(p); del(p->right,val);}
else
{tlr(p); del(p->left,val);}
}
}
else
p->wgt--;
}
else
{
if (val<p->val) del(p->left,val);
else del(p->right,val);
}
if (p!=NULL) p->Maintain();
}
int kth(treap_node *p,int k)
{
if (k<=p->lsize()) return kth(p->left,k);
if (k>p->lsize()+p->wgt) return kth(p->right,k-p->lsize()-p->wgt);
if (k<=p->lsize()+p->wgt) return p->val;
}
int rank(treap_node *p,int val,int cur)
{
if (val==p->val) return cur+p->lsize();
if (val>p->val&&!p->right) return cur+p->lsize()+p->wgt;
if (val<p->val&&!p->left) return cur;
if (val<p->val) return rank(p->left,val,cur);
if (val>p->val) return rank(p->right,val,cur+p->lsize()+p->wgt);
}
void query(int i,int l,int r,int x,int y,int val)
{
if (x<=l&&y>=r)
{
ans+=rank(seg[i],val,0);
return;
}
if (x<=mid) query(lch,x,y,val);
if (y>mid) query(rch,x,y,val);
}
void delt(int i,int l,int r,int x,int num)
{
if (l==x&&l==r)
{
del(seg[i],num);
return;
}
del(seg[i],num);
if (x<=mid) delt(lch,x,num);
else delt(rch,x,num);
}
void ins(int i,int l,int r,int x,int num)
{
if (l==x&&l==r)
{
insert(seg[i],num);
return;
}
insert(seg[i],num);
if (x<=mid) ins(lch,x,num);
else ins(rch,x,num);
}
int Qsum(int x,int y)
{
int t=0,f1=tree[x].top,f2=tree[y].top;
while (f1!=f2)
{
//cout<<x<<' '<<y<<' '<<f1<<' '<<f2<<endl;
if (tree[f1].dep<tree[f2].dep) {swap(x,y); swap(f1,f2);}
t+=plc[x]-plc[f1]+1;
x=tree[f1].fat; f1=tree[x].top;
}
if (tree[x].dep>tree[y].dep) swap(x,y);
t+=plc[y]-plc[x]+1;
return t;
}
void Q(int x,int y,int num)
{
int f1=tree[x].top,f2=tree[y].top;
while (f1!=f2)
{
if (tree[f1].dep<tree[f2].dep) {swap(x,y); swap(f1,f2);}
query(1,1,n,plc[f1],plc[x],num);
x=tree[f1].fat; f1=tree[x].top;
}
if (tree[x].dep>tree[y].dep) swap(x,y);
query(1,1,n,plc[x],plc[y],num);
}
void work(int x,int y,int k)
{
int l,r,t,midx,len;
l=1; r=n;
len=Qsum(x,y);
if (k>len) {printf("invalid request!\n"); return;}
k=len-k+1;
while (l<r)
{
midx=(l+r+1)/2;
t=kth(seg[1],midx);
ans=0; Q(x,y,t);
if (ans<=k-1) l=midx;
else r=midx-1;
}
printf("%d\n",kth(seg[1],l));
}
int main()
{
int i,x,y,k;
scanf("%d%d",&n,&m);
for (i=1;i<=n;++i)
scanf("%d",&a[i]);
for (i=1;i<n;++i)
{
scanf("%d%d",&x,&y);
add(x,y);
}
build_tree(1,0,0);
build_seg(1,1);
build(1,1,n);
for (i=1;i<=m;++i)
{
scanf("%d%d%d",&k,&x,&y);
if (k==0)
{
delt(1,1,n,plc[x],a[x]);
ins(1,1,n,plc[x],y);
a[x]=y;
}
if (k>0)
work(x,y,k);
}
}
【BZOJ 1146】【CTSC 2008】网络管理network的更多相关文章
- 【BZOJ 1146】[CTSC2008]网络管理Network
树剖+树状数组套线段树O(nlogn^3)(我打的),有一种更加优秀的算法是O(nlogn^2)的就是直接树状数组套线段树欧拉序(并不快),或者是用主席树维护原始的树的信息,同时用树状数组套线段树维护 ...
- BZOJ 1146: [CTSC2008]网络管理Network [树上带修改主席树]
1146: [CTSC2008]网络管理Network Time Limit: 50 Sec Memory Limit: 162 MBSubmit: 3522 Solved: 1041[Submi ...
- BZOJ 1146: [CTSC2008]网络管理Network 树链剖分+线段树+平衡树
1146: [CTSC2008]网络管理Network Time Limit: 50 Sec Memory Limit: 162 MBSubmit: 870 Solved: 299[Submit] ...
- BZOJ 1146: [CTSC2008]网络管理Network( 树链剖分 + 树状数组套主席树 )
树链剖分完就成了一道主席树裸题了, 每次树链剖分找出相应区间然后用BIT+(可持久化)权值线段树就可以完成计数. 但是空间问题很严重....在修改时不必要的就不要新建, 直接修改原来的..详见代码. ...
- 【BZOJ-1146】网络管理Network DFS序 + 带修主席树
1146: [CTSC2008]网络管理Network Time Limit: 50 Sec Memory Limit: 162 MBSubmit: 3495 Solved: 1032[Submi ...
- [BZOJ1146][CTSC2008]网络管理Network
[BZOJ1146][CTSC2008]网络管理Network 试题描述 M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个 部门之间协同工作,公司搭建 ...
- Luogu4175:[CTSC2008]网络管理Network
题面 Luogu4175:[CTSC2008]网络管理Network Sol 路径第\(k\)大 无解直接判断就好了 然后整体二分,加上树链剖分+树状数组统计 # include <bits/s ...
- [BZOJ 1013][JSOI 2008] 球形空间产生器sphere 题解(高斯消元)
[BZOJ 1013][JSOI 2008] 球形空间产生器sphere Description 有一个球形空间产生器能够在n维空间中产生一个坚硬的球体.现在,你被困在了这个n维球体中,你只知道球 面 ...
- 【BZOJ1146】[CTSC2008]网络管理Network 树状数组+DFS序+主席树
[BZOJ1146][CTSC2008]网络管理Network Description M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工 ...
- 从多种角度看[BZOJ 1061] [NOI 2008]志愿者招募(费用流)
从多种角度看[BZOJ 1061] [NOI 2008]志愿者招募(费用流) 题面 申奥成功后,布布经过不懈努力,终于成为奥组委下属公司人力资源部门的主管.布布刚上任就遇到了一个难题:为即将启动的奥运 ...
随机推荐
- 温习 socket http tcp
Socket是一个接口,可以实现TCP或者UDP的传输HTTP是协议 资料: 1.TCP/IP连接 手机能够使用联网功能是因为手机底层实现了TCP/IP协议,可以使手机终端通过无线网络建立TCP连接. ...
- VS Code在本地进行调试和打开本地服务器
进行本地调试 1.在扩展中搜索插件 Debugger for Chrome 进行安装.我已经进行了安装,就没有出现安装字样. 2.配置launch.json文件,根据步骤来.file就是你在浏览器中需 ...
- gitlab-ce-11.0.1 安装及汉化
1.添加gitlab源(我这里使用了清华大学的源)cat <<EOF> /etc/yum.repos.d/gitlab-ce.repo[gitlab-ce]name=gitlab-c ...
- 深度学习2015年文章整理(CVPR2015)
国内外从事计算机视觉和图像处理相关领域的著名学者都以在三大顶级会议(ICCV.CVPR和ECCV)上发表论文为荣,其影响力远胜于一般SCI期刊论文.这三大顶级学术会议论文也引领着未来的研究趋势.CVP ...
- 说说第二次配置Ubuntu14.04
任务下达.要装几台linux电脑.并配置能远程--事实上一開始我是拒绝的,内心里百般不想去做.由于干过一次.知道这活儿非常麻烦,这次又有新需求.技术上有非常多还不会.须要花费时间查资料.当时大概预计了 ...
- php中str_repeat函数
php中str_repeat函数 一.作用 用于repeat str 二.实例:输出菱形 代码: <!DOCTYPE html> <html lang="en"& ...
- 浏览器下管理Linux系统--记webmin的使用
本文介绍一款浏览器方式来管理linux的一种方式,这款软件就叫webmin,Webmin 让您能够在远程使用支持 HTTPS (SSL 上的 HTTP)协议的 Web 浏览器通过 Web 界面管理您的 ...
- unity3d编程日志
2014/4/27 编写脚本的时候,加入了中文凝视,发现console面板有非常多不可思议的bug.查了一下发现是由于monodevelop脚本中文凝视报错,而英文凝视不会受影响. 解决方法:把凝视放 ...
- android sdk 镜象网站
因为一些原因.Google相关非常多服务都无法訪问,所以在非常多时候我们SDK也无法升级,当然通过技术手段肯定能够解决,可是比較麻烦,并且下载速度也不怎么样. 这里笔者介绍一个国内的Android镜像 ...
- 4.dubbo-demo+简易监控中心安装+管理控制台安装
转自:https://blog.csdn.net/zhangweigangweiwu/article/details/52244099 tomcat:apache-tomcat-6.0.39 需要用到 ...