jzoj5433. 훈련 집합 NOIP2017 [10.28]도를 향상시킬 수있다.

기술

에지의 n 개의 점 A + B에는 접속 그래프, 변수 X, 각 에지의 중량 부가 K + X, B의 값이 오른쪽 측면을 갖는 X에 대하여, 간단한 다항식 없다 전용 폼 K + 에지 (X)의 중량을 유지할 경우에는 에지의 가중치만을 형성 KX 에지의 무게를 유지하는 경우,이 수치는, 연결된 그래프 남아 KX이고,이 도면은 연결된 그래프 남아있다.
을 감안할 때 질의 q 그룹은, 각각의 도전 x 값은이 경우에는 Q는 방법도와 통신하는 스패닝 트리 최소 무게 없다 주어진다.

입력

네 행의 첫번째 N 개의, A, B 및 Q
U는 V, K는, U 및 V 사이의 정수 표현 세 옆 라인없이 K + X 측에 무게
후속 B 세 라인의 정수 U, V는, K는 가중치는 U 및 V 사이 KX 방향성 에지로 표현
도 최소 생성 물었을 때 다음 라인 Q 각 정수 V, X = (V)를 얼마나 많은 무게를 트리

산출

총 Q 출력 라인은 각 행은 질의 응답에 대응하는 수를 나타낸다

샘플 입력

5 4 4 4
1 3 2
1 0 2
3 5 5
3 4 10
5 4 7
2 3 6
1 2 1000
3 1000 4
0
1
2
3

샘플 출력

14
16
18
18

데이터 제약

데이터의 30 % \. (1 <= N-, Q <= 1000, N--. 1 <= A, B <= 2,000 \)
는 데이터의 다른 20 %, 폼의 모든 가중치 \ (K + X \) 의 사이드 K 만족, \ (0 <= K <= 10 ^. 8 \) 양식 KX 측의 모든 가중치 만족 케이 \. (9 * 10 ^. 8 <= K <= 10 ^. 9 \) , 모든 문의 V 만족 \ (0 <= V <=
4 * 10 ^ 8 \) 는 데이터의 또 다른 40 % \ (1 <= N -. <= 1000,1 <= Q <= 100000 ,. 1 -N - <= A, B <2,000 = \)
데이터의 100 %에 \ (1 <= N-, Q <= 100000 ,. 1 -N -.. <= A, B <= 200000, 0 <= K <= 10 9 ^ ^ -10 9 < V = <= 10 ^ 9 \ )

경기

아무것도 마음 게임, 불과 50 분 재생이 참조 뇌는 지속되지 않습니다.
사실, 100도 ~ 아 생각하는 것은 매우 쉽습니다
필요가 LCT를 사용할 수 있지만, 그러나 캐주얼 폭력 그들은 또한 90 점을 가지고있다.
혈액 손실.

문제 해결

우리는 확실히 경우가 있음을 발견, (A)의 스패닝 트리 최소한도 B. 가능성이
그래서 우리는 MST의 양쪽을 수행하고, 다른 측면이 분명히 없었던 이러한 측면을 유지.
최소 스패닝 트리가 점차 B. 될 때 우리는 x가 커지면, 마법의 물건을 찾을 수 있습니다
변화가 실제로 일부 최소 스패닝 트리가 A 측에서 제거가되는 방법에 관해서는, 사이드 B가 추가됩니다.
여기에 그림 삽입 설명
그것은 다음과 같은 도면을 여러 도면에 의해 발견 될 수 있으며, 실제로, 이러한 변경 프로세스는 :
(1) 첫째, 오름차순 B 값의 K 에지.
도 2는 에지 i 번째를 얻을 수있는 전류를 가정하면,이 에지는 명백 최대 전류 링에게 측을 대체 할 것이다.
도 3에서, x> (값 P [I]를 벗어나는) 경우에 발견 될 수 있는지의 감 P [i]는, 현재의 i가 토륨 측면 대체 될 수있다.
위의 과정은 LCT을 유지하는 데 사용할 수 있습니다. (물론, 아름답게 직접 폭력 수)
있으므로 대체 할 X>는이 때 P는 [I]의 각 에지에 대해 계산.
행 순서는, 각각의 절반은 질문 할 수있다.

표준 프로세스

#include<cstdio>
#include<iostream>
using namespace std;
const int maxn=400010;

struct node{
    long long pf,fa,son[2],key,sum,tag,max,wz,val,id;
}t[maxn]; 

long long q,A,B,f[maxn],d[maxn],wz,zd,op,gs;
long long z[maxn*2],x[maxn*2],y[maxn*2],v,n,m,anss[maxn],answ[maxn],xx,answer[maxn];
long long ax[maxn],ay[maxn],az[maxn],jax[maxn],jay[maxn],jaz[maxn];
long long bx[maxn],by[maxn],bz[maxn],jbx[maxn],jby[maxn],jbz[maxn];

void make(int x)
{
    swap(t[x].son[0],t[x].son[1]);
    t[x].tag^=1;
}

void update(int x)
{
    t[x].sum=t[t[x].son[0]].sum+t[t[x].son[1]].sum+t[x].key;
    t[x].max=t[t[x].son[0]].max;t[x].wz=t[t[x].son[0]].wz;
    if (t[t[x].son[1]].max>t[x].max) 
    {
        t[x].max=t[t[x].son[1]].max;t[x].wz=t[t[x].son[1]].wz;
    }
    if (t[x].val>t[x].max)
    {
        t[x].max=t[x].val;t[x].wz=t[x].id;
    }
}

void clear(int x)
{
    if(t[x].tag)
    {
        make(t[x].son[0]),make(t[x].son[1]);
        t[x].tag=0;
    }
}

void remove(int x,int y)
{
    for (d[0]=0;x!=y;x=t[x].fa) d[++d[0]]=x;
    for (int i=d[0];i>=1;--i) clear(d[i]);
}

int get(int x)
{
    return t[t[x].fa].son[1]==x;
}

void rotate(int x)
{
    int y=t[x].fa,k=get(x);
    if(t[y].fa) t[t[y].fa].son[get(y)]=x;
    if(t[x].son[!k]) t[t[x].son[!k]].fa=y;
    t[y].son[k]=t[x].son[!k],t[x].fa=t[y].fa,t[y].fa=x,t[x].son[!k]=y;
    update(y),update(x),t[x].pf=t[y].pf;
}

void splay(int x,int y)
{
    remove(x,y);
    while(t[x].fa!=y)
    {
        if(t[t[x].fa].fa!=y)
            if(get(x)==get(t[x].fa)) rotate(t[x].fa);
            else rotate(x);
        rotate(x);
    }
}

void access(int x)
{
    for (int y=0;x;update(x),y=x,x=t[x].pf)
    {
        splay(x,0);
        t[t[x].son[1]].fa=0,t[t[x].son[1]].pf=x;
        t[x].son[1]=y,t[y].fa=x,t[y].pf=0;
    }
}

int findroot(int x)
{
    access(x),splay(x,0);
    for (;t[x].son[0];x=t[x].son[0]);
    return x;
}

void makeroot(int x)
{
    access(x),splay(x,0);
    make(x);
}

void query(int x,int y)
{
    makeroot(x),access(y);
    splay(y,0);
    wz=t[y].wz;
    zd=t[y].max;
}

void link(int x,int y)
{
    makeroot(x);
    if(findroot(y)!=x) t[x].pf=y;
}

void cut(int x,int y)
{
    makeroot(x),access(y),splay(y,0);
    if(t[x].fa==y) t[y].son[get(x)]=t[x].fa=t[x].pf=0;
}

void change(int x,int y)
{
    splay(x,0);
    t[x].key=y,update(x);
}

int getfather(int x)
{
    if (f[x]==x) return x;
    f[x]=getfather(f[x]);
    return f[x];
}

void qsort(int l,int r)
{
    int i=l;int j=r;
    long long m=z[(i+j)/2];
    while (i<=j)
    {
        while (z[i]<m) i++;
        while (z[j]>m) j--;
        if (i<=j)
        {
            swap(z[i],z[j]);
            swap(x[i],x[j]);
            swap(y[i],y[j]);
            i++;j--;
        }
    }
    if (l<j) qsort(l,j);
    if (r>i) qsort(i,r); 
}

void qsort1(int l,int r)
{
    int i=l;int j=r;
    long long m=anss[(i+j)/2];
    while (i<=j)
    {
        while (anss[i]<m) i++;
        while (anss[j]>m) j--;
        if (i<=j)
        {
            swap(anss[i],anss[j]);
            swap(answ[i],answ[j]);
            i++;j--;
        }
    }
    if (l<j) qsort1(l,j);
    if (r>i) qsort1(i,r); 
}

int main()
{
    freopen("graph.in","r",stdin);
    freopen("graph.out","w",stdout);
    scanf("%d%d%d%d",&n,&A,&B,&m);
    for (int i=0;i<=n;i++)
    {
        t[i].val=-1000000000000;t[i].key=0;t[i].max=t[i].val;
    }
    for (int i=1;i<=A;i++) scanf("%lld%lld%lld",&ax[i],&ay[i],&az[i]);
    for (int i=1;i<=B;i++) scanf("%lld%lld%lld",&bx[i],&by[i],&bz[i]);
    
    int gs=0;
    for (int i=1;i<=A;i++)
    {
        gs++;
        x[gs]=ax[i];y[gs]=ay[i];z[gs]=az[i];
    }
    qsort(1,gs);
    for (int i=1;i<=n;i++) f[i]=i;
    for (int i=1;i<=gs;i++)
    {
        int xx=getfather(x[i]);
        int yy=getfather(y[i]);
        if (xx!=yy)
        {
            f[xx]=yy;
            op++;
            jax[op]=x[i];jay[op]=y[i];jaz[op]=z[i];
            t[op+n].id=op;t[op+n].val=z[i];t[op+n].key=z[i];t[op+n].max=t[op+n].val;
            anss[0]+=z[i]; 
        }
    }
    
    for (int i=1;i<=op;i++)
    {
        link(jax[i],i+n);
        link(i+n,jay[i]);
    }
    makeroot(1);
    
    gs=0;
    for (int i=1;i<=B;i++)
    {
        gs++;
        x[gs]=bx[i];y[gs]=by[i];z[gs]=bz[i];
    }
    qsort(1,gs);
    for (int i=1;i<=n;i++) f[i]=i;
    int pp=0;
    for (int i=1;i<=gs;i++)
    {
        int xx=getfather(x[i]);
        int yy=getfather(y[i]);
        if (xx!=yy)
        {
            if (i==135)
            {
                int j=0;
            }
            f[xx]=yy;
            op++;pp++;
            jbx[op]=x[i];jby[op]=y[i];jbz[op]=z[i];
            query(x[i],y[i]);
            anss[pp]=z[i]-jaz[wz];
            if ((z[i]-jaz[wz])%2==1) answ[pp]=(z[i]-jaz[wz])/2+1; else answ[pp]=(z[i]-jaz[wz])/2;
            cut(jax[wz],n+wz);cut(n+wz,jay[wz]);
            t[op+n].id=op;t[op+n].val=-1000000000000;t[op+n].key=z[i];t[op+n].max=t[op+n].val;
            link(x[i],op+n);link(op+n,y[i]);
        }
    }
    
    qsort1(1,n-1);
    
    answer[0]=anss[0];
    for (int i=1;i<n;i++)
    {
        answer[i]=anss[i]+answer[i-1];
    }
    
    for (int i=1;i<=m;i++)
    {
        scanf("%lld",&xx);
        int l=1;int r=n-1;int k=0;
        while (l<=r)
        {
            int mid=(l+r)/2;
            if (xx>=answ[mid])
            {
                k=mid;
                l=mid+1;
            }
            else r=mid-1;
        }
        printf("%lld\n",answer[k]+(n-1-2*k)*xx);
    }
} 

추천

출처www.cnblogs.com/RainbowCrown/p/11593263.html