[NOIP2015]运输计划 线段树or差分二分

目录

  • [NOIP2015]运输计划
    • 链接
    • 思路1 暴力数据结构
    • 思路2 二分树上差分
    • 总的
    • 代码1
    • 代码2

[NOIP2015]运输计划

链接

luogu
好久没写博客了,水一篇波。

思路1 暴力数据结构

枚举最长链的边,删除后代价为(最长链-边权,不经过这条边的链)的最大值。
不经过某条边的最大值要用线段树维护补集。
复杂度\(O(nlog^2n)\)

思路2 二分树上差分

二分答案,删除的边为\(>mid\)的链的交集。
用树上查分维护交集。
最后在交集中找个最大的边删除就好了。
复杂度\(O(nlogn)\)

总的

思路2,复杂度小,好写,简单,细节少。
思路1,复杂度高,码量大,细节多,并不是呢么好想。
所以并不是很建议写第一种。
但他靠着树剖的小常数跑过了树上差分(至少我是这样,1.9s->1.2s)。

代码1

#include 
using namespace std;
const int _=5e5+7;
int read() {
    int x=0,f=1;char s=getchar();
    for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
    for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
    return x*f;
}
int n,m,ans,u[_],v[_],dsr[_],w[_];
struct node {
    int v,nxt,q,w;
}e[_<<1];
int head[_],tot;
void add(int u,int v,int q) {
    e[++tot].v=v;
    e[tot].q=q;
    e[tot].nxt=head[u];
    head[u]=tot;
}
int f[_],dep[_],siz[_],son[_],top[_],idx[_],dis[_],nb[_],cnt;
void dfs1(int u,int fa) {
    dep[u]=dep[fa]+1;
    f[u]=fa;
    siz[u]=1;
    for(int i=head[u];i;i=e[i].nxt) {
        int v=e[i].v;
        if(v==fa) continue;
        w[v]=e[i].q;
        dis[v]=dis[u]+e[i].q;
        dfs1(v,u);
        siz[u]+=siz[v];
        if(siz[son[u]]R) return;
        if(L<=l&&r<=R) return tag(rt,val);
        int mid=(l+r)>>1;
        pushdown(rt);
        if(L<=mid) modify(L,R,val,l,mid,ls);
        if(R>mid) modify(L,R,val,mid+1,r,rs);
        ma[rt]=max(ma[ls],ma[rs]);
    }
    void dfs(int l,int r,int rt) {
        if(l==r) return void(dsr[nb[l]]=ma[rt]);
        int mid=(l+r)>>1;
        pushdown(rt);
        if(l<=mid) dfs(l,mid,ls);
        if(r>mid) dfs(mid+1,r,rs);
    }
}
int lca(int x,int y) {
    while(top[x]!=top[y]) {
        if(dep[top[x]]

代码2

#include 
using namespace std;
const int _=5e5+7;
int read() {
    int x=0,f=1;char s=getchar();
    for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
    for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
    return x*f;
}
int n,m,ans,u[_],v[_],LCA[_],len[_],the_biggest,w[_];
struct node {
    int v,nxt,q;
}e[_<<1];
int head[_],tot;
void add(int u,int v,int q) {
    e[++tot].v=v;
    e[tot].q=q;
    e[tot].nxt=head[u];
    head[u]=tot;
}
int f[_],dep[_],siz[_],son[_],dis[_],top[_],cnt;
void dfs1(int u,int fa) {
    dep[u]=dep[fa]+1,f[u]=fa,siz[u]=1;
    for(int i=head[u];i;i=e[i].nxt) {
        int v=e[i].v;
        if(v==fa) continue;
        w[v]=e[i].q;
        dis[v]=dis[u]+e[i].q;
        dfs1(v,u);
        siz[u]+=siz[v];
        if(siz[son[u]]>1;
        if(check(mid)) ans=mid,r=mid-1;
        else l=mid+1;
    } cout<

你可能感兴趣的:([NOIP2015]运输计划 线段树or差分二分)