FCS省选模拟赛 Day4

传送门

Solution


Code 

/*
    斯坦纳树;O(n*3^n+kE*2^n) 暂且把O(k*E)当成是spfa的复杂度
    15:15~16:20 原题:bzoj_4774 
*/
#include<bits/stdc++.h>
#define ll long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    return x*f;
}
const int MN=105,MM=1005,inf=0x3f3f3f3f;
int n,m,k;
struct edge{int to,w,nex;}e[MM<<1];int hr[MN],en;
inline void ins(int f,int t,int w)
{
    e[++en]=(edge){t,w,hr[f]};hr[f]=en;
    e[++en]=(edge){f,w,hr[t]};hr[t]=en;
}
std::queue<int> q;
int f[1<<11][MN],g[1<<11],refer[1<<6],ans=inf;
bool inq[MN];
void spfa(int *d)
{
    register int u,i;
    while(!q.empty())
    {
        u=q.front();q.pop();inq[u]=false;
        for(i=hr[u];i;i=e[i].nex)
            if(d[e[i].to]>d[u]+e[i].w)
            {
                d[e[i].to]=d[u]+e[i].w;
                if(!inq[e[i].to]) q.push(e[i].to),inq[e[i].to]=true;
            }
    }
}
int main()
{
    register int i,j,x,y,S,SS,SSS,s;
    n=read();m=read();k=read();SS=1<<k;SSS=1<<(k>>1);
    while(m--)x=read(),y=read(),ins(x,y,read());
    memset(f,0x3f,sizeof f);
    for(i=1;i<=k;++i) f[1<<i-1][i]=0;
    for(S=1;S<SS;++S)
    {
        for(i=1;i<=n;++i)
        {
            for(s=S&(S-1);s;s=(s-1)&S) f[S][i]=min(f[S][i],f[s][i]+f[S^s][i]);
            if(f[S][i]<inf) q.push(i);
        }
        spfa(f[S]);g[S]=inf;
        for(i=1;i<=n;++i) g[S]=min(g[S],f[S][i]);
    }
    for(i=0;i<SSS;++i)
    {
        s=0;
        for(j=0;j<k/2;++j) if(i>>j&1) s|=1<<(j*2);
        refer[i]=s|(s<<1);
    }
    for(S=1;S<SSS;++S)for(s=S&(S-1);s;s=(s-1)&S)
        g[refer[S]]=min(g[refer[S]],g[refer[s]]+g[refer[S^s]]);
    printf("%d\n",g[SS-1]);
    return 0;
}


#include<bits/stdc++.h>
#define ll long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    return x*f;
}
#define int ll
const int MN=1e5+5;
int N,A[MN],w[MN],L[MN],R[MN],M;
int K[MN][350],Ll[350],Rr[350],bl,bel[MN];
int t[MN];
ll qz_a_1[350],qz_a_2[MN],sum_f[350];
void C(int x,int y){for(;x<=N;x+=(x&-x))t[x]+=y;}
int G(int x){int r=0;for(;x;x-=(x&-x))r+=t[x];return r;}

struct edge{int to,nex;}e[MN<<1];int hr[MN],en,ind;
inline void Ins(int f,int t){e[++en]=(edge){t,hr[f]};hr[f]=en;}
inline void ins(int f,int t){Ins(f,t);Ins(t,f);}
inline void dfs(int x,int f)
{
    register int i;L[x]=++ind;A[ind]=w[x];
    for(i=hr[x];i;i=e[i].nex)if(e[i].to^f)dfs(e[i].to,x);
    R[x]=ind;
}
signed main()
{
    register int i,j,Q,opt,x,y,rt;
    N=read();M=(int)((double)sqrt(N)+.5);Q=read();
    for(i=1;i<=N;++i) w[i]=read();
    for(i=1;i<=N;++i)
    {
        x=read();y=read();
        if(!x) rt=y;
        ins(x,y);
    }
    dfs(rt,0);
    for(bl=0,i=1;i<=N;++i)
    {
        C(L[i],1),C(R[i]+1,-1);
        if(i==N||i%M==0)
        {
            ++bl;Rr[bl]=i;
            for(j=1;j<=N;++j) K[j][bl]=G(j);
            for(Ll[bl]=j=(bl-1)*M+1;j<=i;++j) bel[j]=bl,C(L[j],-1),C(R[j]+1,1);
        }
    }
    for(i=1;i<=N;++i) qz_a_2[i]=qz_a_2[i-1]+A[i];
    for(i=1;i<=bl;++i) qz_a_1[i]=qz_a_2[Rr[i]];
    for(i=1;i<=N;++i) qz_a_2[i]-=qz_a_1[bel[i]-1];
    #define cal(x) (qz_a_1[bel[x]-1]+qz_a_2[x])
    for(i=1;i<=bl;++i)for(j=Ll[i];j<=Rr[i];++j)sum_f[i]+=cal(R[j])-cal(L[j]-1);
    while(Q--)
    {
        opt=read(),x=read(),y=read();
        if(opt==1)
        {
            x=L[x];y-=A[x];
            for(i=bel[x];i<=bl;++i) qz_a_1[i]+=y;
            for(i=x;i<=Rr[bel[x]];++i) qz_a_2[i]+=y;
            for(i=1;i<=bl;++i) sum_f[i]+=1ll*y*K[x][i];
            A[x]+=y;
        }
        if(opt==2)
        {
            ll ans=0;
            if(bel[x]==bel[y]) for(i=x;i<=y;++i) ans+=cal(R[i])-cal(L[i]-1);
            else
            {
                for(i=bel[x]+1;i<=bel[y]-1;++i) ans+=sum_f[i];
                for(i=x;i<=Rr[bel[x]];++i) ans+=cal(R[i])-cal(L[i]-1);
                for(i=Ll[bel[y]];i<=y;++i) ans+=cal(R[i])-cal(L[i]-1);
            }
            printf("%lld\n",ans);
        }   
    }
    #undef cal
    return 0;
}


/*
    每条边都有一个存在时间[l,r],每个询问相当于求一个时刻的答案
    可以用线段树分治来维护
    要支持操作是可逆的,所以采用按秩合并的dsu
    2019/3/21 by pac 
*/
#include<bits/stdc++.h>
#define ll long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    return x*f;
}
#define reg register
const int MN=7e4+5;
int N,M,ans[MN];
std::vector<int>id[MN];
struct edge{int u,v,nex,l,r;}e[MN<<1];int en,hr[MN];
void ins(int f,int t,int l,int r)
{
    e[++en]=(edge){f,t,hr[f],l,r};hr[f]=en;
    e[++en]=(edge){t,f,hr[t],l,r};hr[t]=en;
}
class LCA
{
    int siz[MN],fa[MN],mx[MN],top[MN],dep[MN];
    void dfs1(int x,int f)
    {
        dep[x]=dep[f]+1;fa[x]=f;siz[x]=1;reg int i;
        for(i=hr[x];i;i=e[i].nex)if(e[i].v^f)
            dfs1(e[i].v,x),siz[x]+=siz[e[i].v],siz[e[i].v]>siz[mx[x]]?mx[x]=e[i].v:0;
    }
    void dfs2(int x,int f,int tp)
    {
        top[x]=tp;if(mx[x])dfs2(mx[x],x,tp);reg int i;
        for(i=hr[x];i;i=e[i].nex)if((e[i].v^f)&&(e[i].v^mx[x]))
            dfs2(e[i].v,x,e[i].v);
    }
    public:
        void init(){dfs1(1,0);dfs2(1,0,1);}
        int dis(int x,int y)
        {
            if(!x||!y) return 0;
            int r=dep[x]+dep[y];
            for(;top[x]^top[y];) dep[top[x]]>dep[top[y]]?x=fa[top[x]]:y=fa[top[y]];
            return r-2ll*min(dep[x],dep[y]);
        }
}T;
struct Ans
{
    int dl,dr,len;
    Ans Max(const Ans &o,const Ans &oo){return o.len>oo.len?o:oo;}
    Ans operator *(const Ans &o)
    {
        Ans r=Max(*this,o);
        r=Max(r,(Ans){dl,o.dl,T.dis(dl,o.dl)});
        r=Max(r,(Ans){dl,o.dr,T.dis(dl,o.dr)});
        r=Max(r,(Ans){dr,o.dl,T.dis(dr,o.dl)});
        r=Max(r,(Ans){dr,o.dr,T.dis(dr,o.dr)});
        return r;
    }
};
class DSU
{
    Ans bl[MN],st_ori[MN];
    int fa[MN],siz[MN],tp,st_l[MN],st_r[MN],ans;
    int getf(int x){return x==fa[x]?x:getf(fa[x]);}
    public:
        void init()
        {
            tp=0;ans=0;reg int i;
            for(i=1;i<=N;++i) fa[i]=i,siz[i]=1,bl[i]=(Ans){i,i,0};
        }
        void union_(int x,int y)
        {
            //if(getf(x)==19&&getf(y)==4) printf("%d %d\n",x,y);
            x=getf(x);y=getf(y);
            //printf("combine %d %d\n",x,y);
            if(x==y) return;
            if(siz[x]<siz[y]) std::swap(x,y);
            siz[x]+=siz[y];st_l[++tp]=x;st_r[tp]=y;
            fa[y]=x;st_ori[tp]=bl[x];bl[x]=bl[x]*bl[y];
            ans=max(ans,bl[x].len);
            //if(x==19&&bl[x].len==3) printf("find %d %d\n",y,bl[y].len);
        }
        void getori(int to,int p)
        {
            reg int l,r;
            for(;tp>to;--tp)
            {
                l=st_l[tp],r=st_r[tp];
            //  printf("break %d %d\n",l,r);
                siz[l]-=siz[r];fa[r]=r;
                bl[l]=st_ori[tp];
            }
            ans=p;
        }
        int Tp(){return tp;}
        int ANs(){return ans;}
    //  void print()
    //  {
    //      printf("Ans=%d\n",ans);
    //      for(int i=1;i<=20;++i) printf("%d: %d\n",i,bl[i].len);
    //  }
}dsu;
std::vector<int> T_ed[MN<<2];
void Md(int k,int l,int r,int a,int b)
{
    if(l==a&&r==b){T_ed[k].push_back(en);return;}
    int mid=(l+r)>>1;
    if(b<=mid) Md(k<<1,l,mid,a,b);
    else if(a>mid) Md(k<<1|1,mid+1,r,a,b);
    else Md(k<<1,l,mid,a,mid),Md(k<<1|1,mid+1,r,mid+1,b);
}
void Solve(int x,int l,int r)
{
    reg int pre=dsu.Tp(),i,res=dsu.ANs();
    for(i=T_ed[x].size()-1;~i;--i){dsu.union_(e[T_ed[x][i]].u,e[T_ed[x][i]].v);}
    if(l==r)
    {
    //  if(l==15) dsu.print();
        for(i=id[l].size()-1;~i;--i) ans[id[l][i]]=dsu.ANs();
    }
    if(l!=r)
    {
        reg int mid=(l+r)>>1;
        Solve(x<<1,l,mid);Solve(x<<1|1,mid+1,r);
    }
    dsu.getori(pre,res);
}
int main()
{
//  freopen("racing1.in","r",stdin);
//  freopen("racing1.out","w",stdout);
    N=read();M=read();
    register int i,x,y,l,r;
    for(i=1;i<N;++i)
    {
        x=read(),y=read();l=read(),r=read();
        ins(x,y,l,r);Md(1,1,N,l,r);
    //  printf("%d %d %d %d\n",x,y,l,e[en].r);
    }
    for(i=1;i<=M;++i) id[read()].push_back(i);
    T.init();dsu.init();Solve(1,1,N);
    for(i=1;i<=M;++i) printf("%d\n",ans[i]);
}



Blog来自PaperCloud,未经允许,请勿转载,TKS!

转载于:https://www.cnblogs.com/PaperCloud/p/fcs_noi2019_day4.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值