您的位置:首页 > 理论基础 > 计算机网络

bzoj4538 [Hnoi2016]网络

2016-04-20 20:50 369 查看
  比较容易想到的做法是树链剖分,每个线段树节点维护一个集合,对于一个修改路径操作,我们可以将线段树上不包含操作路径的节点的区间全部都进行一次修改,这种区间个数是logn级别的,这样询问的复杂度是O(qlogn),修改的复杂度是O(q(logn^3)),居然给卡过了。。。

  代码

#include<cstdio>
#include<algorithm>
#include<vector>
#include<set>
#define mp make_pair
#define pb push_back
#define fi first
#define sc second
#define N 600000
using namespace std;
typedef long long ll;
int n,m,a,b,i,dp,deep
;
int pre
,p
,tt
,f
,size
,go
,gf
,id
,tot;
int l
,r
;
multiset<int> s
;
vector<pair<int,int> >vec;
struct Q{
int l,r,w,typ;
}q
;
void link(int x,int y)
{
dp++;pre[dp]=p[x];p[x]=dp;tt[dp]=y;
}
void dfs1(int x,int fa)
{
int i=p[x];
size[x]=1;
while (i)
{
if (tt[i]!=fa)
{
deep[tt[i]]=deep[x]+1;
dfs1(tt[i],x);
if (size[tt[i]]>size[go[x]]) go[x]=tt[i];
size[x]+=size[tt[i]];
}
i=pre[i];
}
}
void dfs2(int x,int fa,int Fa)
{
int i=p[x];
tot++;id[x]=tot;gf[x]=Fa;f[x]=fa;
if (go[x]) dfs2(go[x],x,Fa);
while (i)
{
if ((tt[i]!=fa)&&(tt[i]!=go[x]))
dfs2(tt[i],x,tt[i]);
i=pre[i];
}
}
void build(int x,int a,int b)
{
l[x]=a;r[x]=b;
if (b-a>1)
{
int m=(a+b)>>1;
if (a<m) build(2*x,a,m);
if (m<b) build(2*x+1,m,b);
}
}
void change(int x,int a,int b,int c)
{
if ((a<=l[x])&&(r[x]<=b))
{
if (c>0)
s[x].insert(c);
else
s[x].erase(s[x].find(-c));
return;
}
int m=(l[x]+r[x])>>1;
if (a<m) change(2*x,a,b,c);
if (m<b) change(2*x+1,a,b,c);
}
int query(int x,int a,int b)
{
int ans;
if (s[x].empty()) ans=-1;else ans=*(--s[x].end());
if ((a<=l[x])&&(r[x]<=b)) return ans;
int m=(l[x]+r[x])>>1;
if (a<m)ans=max(ans,query(2*x,a,b));
if (m<b)ans=max(ans,query(2*x+1,a,b));
return ans;
}
void gao(int a,int b,int c)
{
vec.clear();
int cnt=0;
while (1)
{
int da=deep[gf[a]],db=deep[gf[b]];
if ((da<db)||(da==db)&&(deep[a]<deep[b])) a^=b^=a^=b;
if (gf[a]==gf[b])
{
vec.pb(mp(id[b],id[a]));
break;
}
else
{
vec.pb(mp(id[gf[a]],id[a]));
a=f[gf[a]];
}
}
sort(vec.begin(),vec.end());
int head=0;
for (int i=0;i<vec.size();i++)
{
if (head!=vec[i].fi-1)
change(1,head,vec[i].fi-1,c);
head=vec[i].sc;
}
if (head!=n) change(1,head,n,c);
}
int main()
{
scanf("%d%d",&n,&m);
for (i=1;i<n;i++)
{
scanf("%d%d",&a,&b);
link(a,b);link(b,a);
}
dfs1(1,0);
dfs2(1,0,1);

build(1,0,n);
for (i=1;i<=m;i++)
{
scanf("%d%",&q[i].typ);
if (q[i].typ==2)
{
scanf("%d",&q[i].w);
int tmp=id[q[i].w];
printf("%d\n",query(1,tmp-1,tmp));
}
else
if (q[i].typ==0)
{
scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].w);
gao(q[i].l,q[i].r,q[i].w);
}
else
{
scanf("%d",&q[i].w);
int tmp=q[i].w;
gao(q[tmp].l,q[tmp].r,-q[tmp].w);
}
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: