zoukankan      html  css  js  c++  java
  • 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
    ",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
    ",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
    ",x,y);
    			x=getf(x);y=getf(y);
    			//printf("combine %d %d
    ",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
    ",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
    ",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
    ",ans);
    	//		for(int i=1;i<=20;++i) printf("%d: %d
    ",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
    ",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
    ",ans[i]);
    }
    


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

  • 相关阅读:
    20155322 2016-2017-2 《Java程序设计》第7周学习总结
    高级sed编程
    正则表达式
    实验十二:kvm环境下qemu-kvm创建虚拟机之间的网络配置
    实验十一:了解qemu-kvm的显示选项参数
    实验十:在kvm下创建winxp虚拟机
    实验九:第二个虚拟机的创建(标准选项)
    实验八:kvm环境搭建并创建第一台cirrOS虚拟机
    sed和gawk
    在脚本中添加颜色
  • 原文地址:https://www.cnblogs.com/PaperCloud/p/fcs_noi2019_day4.html
Copyright © 2011-2022 走看看