【JZOJ5433】【NOIP2017提高A组集训10.28】图

Description

有一个n个点A+B条边的无向连通图,有一变量x,每条边的权值都是一个关于x的简单多项式,其中有A条边的权值是k+x,另外B条边的权值是k-x,如果只保留权值形如k+x的边,那么这个图仍是一个连通图,如果只保留权值形如k-x的边,这个图也依然是一个连通图。
给出q组询问,每组询问给出x的值,问此时这个无向连通图的最小生成树权值是多少。

Data Constraint

对于30%的数据,1<=n,q<=1000,n-1<=A,B<=2000
对于另外20%的数据,所有权值形如k+x的边的k满足,0<=k<=10^8,所有权值形如k-x的边的k满足9*10^8<=k<=10^9,所有询问的v满足0<=v<=4*10^8
对于另外40%的数据,1<=n<=1000,1<=q<=100000,n-1<=A,B<=2000
对于100%的数据,1<=n,q<=100000 , n-1<=A,B<=200000, 0<=k<=10^9 , -10^9<=v<=10^9

Solution

显然v的值由-∞变至+∞的过程中最小生成树会由完全有A组成变至完全由B组成,也就是说答案最多变化B次。我们考虑求出这个分界值。我们构出A的最小生成树后,将B的值从小到大加入,每次取代掉环上的最大边并计算出取代的时间,这个用LCT来维护。最后时间从小到大排序。在询问时二分一下即可。但现在问题是若一条较小B边x,它的取代时间k1大于另一条较大B边y的取代时间k2,那用LCT维护改变了树的形态没问题吗?
答案是没问题。
这里写图片描述
加入y取代的最大边在2-5,3-4之间那明显x对y没影响,但有没有可能y取代的最大边在1-2,1-3之间呢?我们发现要是这样,那x也同样可以取代这条最大边,那按照最小生成树的做法,明显x更优,也不会选y,并且由于x< y,上述情况一定是k1< k2。与假设相悖。

Code

#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
const ll maxn=6e5+5;
struct code{
    ll x,y,z;
}c[maxn],d[maxn],g[maxn];
ll fa[maxn],pfa[maxn],f[maxn][2],b[maxn],a[maxn],fa1[maxn],bz[maxn],p1[maxn];
ll n,m,p,q,i,t,j,k,l,x,y,z,num,mx,r,mid;
ll getfa(ll x){return (fa1[x]==x)?x:fa1[x]=getfa(fa1[x]);}
bool cmp(code x,code y){return x.z<y.z;}
ll son(ll x){return f[fa[x]][1]==x;}
ll get(){
    char ch=getchar();ll x=0,z=1;
    while ((ch<48 || ch>57) && ch!='-') ch=getchar();
    if (ch=='-') z=-1;
    while (ch<48 || ch>57) ch=getchar();
    while (ch>=48 && ch<=57) x=x*10+ch-48,ch=getchar();
    return x*z;
}
void remove(ll x){
    while (x) p1[++p1[0]]=x,x=fa[x];
    while (p1[0]){
        if (bz[p1[p1[0]]]) x=p1[p1[0]],swap(f[x][0],f[x][1]),bz[f[x][0]]^=1,bz[f[x][1]]^=1,bz[x]=0;
        p1[0]--;
    }
}
void rotate(ll x){
    b[x]=x;
    if (a[b[f[x][0]]]>a[b[x]]) b[x]=b[f[x][0]];
    if (a[b[f[x][1]]]>a[b[x]]) b[x]=b[f[x][1]];
}
void make(ll x){
    ll y=fa[x],z=son(x);
    f[fa[x]=fa[y]][son(y)]=x;fa[f[y][z]=f[x][1-z]]=y;f[fa[y]=x][1-z]=y;
    swap(pfa[x],pfa[y]);rotate(y);rotate(x);
}
void splay(ll x){
    remove(x);
    while (fa[x]){
        if (fa[fa[x]])
            if (son(x)==son(fa[x])) make(fa[x]);
            else make(x);
        make(x);
    }
}
void access(ll x){
    ll y=0;
    while (x){
        splay(x);
        pfa[f[x][1]]=x;fa[f[x][1]]=0;pfa[f[x][1]=y]=0;fa[y]=x;
        rotate(x);y=x,x=pfa[x];
    }
}
void makeroot(ll x){
    access(x);splay(x);bz[x]^=1;
}
void link(ll x,ll y){
    makeroot(x);pfa[x]=y;
}
void cut(ll x,ll y){
    makeroot(y);access(x);splay(y);fa[x]=pfa[x]=0;rotate(y);
}
void put(ll x){
    if (x<0) putchar('-'),x=-x;
    while (x) p1[++p1[0]]=x%10,x/=10;
    while (p1[0]) putchar(p1[p1[0]--]+48);putchar('\n');
}
int main(){
    freopen("graph.in","r",stdin);freopen("graph.out","w",stdout);
    scanf("%lld%lld%lld%lld",&n,&p,&q,&m);
    memset(a,128,sizeof(a));mx=a[1];
    for (i=1;i<=n+p+q;i++) b[i]=i;
    for (i=1;i<=p;i++)c[i].x=get(),c[i].y=get(),c[i].z=get();
    for (i=1;i<=q;i++)d[i].x=get(),d[i].y=get(),d[i].z=get();
    sort(c+1,c+p+1,cmp);sort(d+1,d+q+1,cmp);
    for (i=1;i<=n;i++)fa1[i]=i;g[num=1].z=mx;
    for (i=1;i<=p;i++){
        a[n+i]=c[i].z;
        x=getfa(c[i].x);
        y=getfa(c[i].y);
        if (x!=y)link(c[i].x,n+i),link(c[i].y,n+i),fa1[y]=x,g[1].x+=c[i].z,g[1].y++;
    }
    for(i=1;i<=q;i++){
        x=d[i].x;y=d[i].y;
        if (x==y) continue;
        makeroot(x);
        makeroot(y);
        if (!pfa[x]&&!fa[x]) link(x,y),g[1].x+=d[i].z,g[1].y--;
        else{
            access(x);splay(x);t=b[x];
            if (a[t]==mx) continue;
            g[++num].z=(d[i].z-a[t])/2+((d[i].z-a[t])%2 && d[i].z>a[t]);g[num].x=d[i].z-a[t];
            cut(t,c[t-n].x);cut(t,c[t-n].y);link(x,y);
        }
    }
    sort(g+1,g+num+1,cmp);
    for (i=2;i<=num;i++)g[i].x+=g[i-1].x,g[i].y=g[i-1].y-2;
    for (i=1;i<=m;i++){
        x=get();
        l=1;r=num;
        while (l<r){
            mid=(l+r+1)/2;
            if (g[mid].z<=x) l=mid;
            else r=mid-1;
        }
        x=g[l].x+g[l].y*x;
        put(x);
    }
}
发布了257 篇原创文章 · 获赞 451 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/crybymyself/article/details/78388768