• 2020牛客暑期多校训练营


    暑假打的是HDU多校,没报牛客,来补补题

    Eazy

    • 题意:给定(n,m,k),求(sumlimits_{{a_i}{b_i},a>0,b>0,|a|=|b|=k}[sumlimits_{j=1}^k a_j=n][sumlimits_{j=1}^k b_j=m]prodlimits_{j=1}^k min(a_j,b_j))
    • 做法:
      考虑二元生成函数
      (egin{aligned}G(x,y)&=sumlimits_{i,j>0}min(i,j)x^iy^j\ &=sumlimits_{i>0}ix^isumlimits_{jge i}y^j+sumlimits_{i>0}iy^isumlimits_{j>i}x^j\ &=sumlimits_{i>0}ix^iy^i(frac{1}{1-y}+frac{x}{1-x})\ &=frac{xy}{1-xy}(frac{1}{1-y}+frac{x}{1-x})\ &=frac{xy}{(1-xy)(1-x)(1-y)}\ end{aligned})
      (Ans=[x^ny^m]G(x,y)^k)

    Easy construction

    • 题意:给定一棵树,多次询问,给出((l,r,x)),求(sumlimits_{lle i<jle r}[lca(i,j)=x])
    • 做法:
      即求({size_xchoose 2}sumlimits_{vin son_x}{size_vchoose 2})
      考虑链分治,对重儿子直接主席树查询;至于轻儿子,可以对((l,r))离线下来莫队,对于每个点(i),计算其到根路径对祖先的贡献。这样复杂度是(O(nlogn+nsqrt{n}logn))
      但是还不够,考虑对树链剖分变形
      对于每个点,令子树大小前(O(sqrt{n}))大的为重儿子,对于每个点,每跳一次轻边,子树大小乘以(O(sqrt{n})),故只会经过(O(1))次轻边
      对于重儿子,即查询对于区间([l',r'])有多少个小于等于某个数的个数,共(O(nsqrt{n}))个查询,对([l',r'])差分处理,配合(O(sqrt{n}))修改-(O(1))查询的值域分块
      总复杂度(O(nsqrt{n}))

    NeoMole Synthesis

    • 题意
    • 做法:
      枚举任意点为(T)的根,由于(sum |T'_i|le 500),讲模板树重新标号,使得不同模板树上无相同节点
      (f_{i,j,k})(T)(i-fa_i)匹配模板树中的(j-k)的最小花费(除正在匹配的这棵树,其他树均匹配完了)。特殊的,若(k=0),则正在匹配的模板树匹配
      (g_i)(T)点的子树全部匹配完的最小花费:(g_i=min(f_{i,j,0}))
      容易发现(f)的转移是二分图完备匹配,用KM算法。总复杂度(O(n^4))
      考虑优化,容易发现(f_{i,j,k_1 eq 0})只用从(f_{i,j,k=0})的二分图中(k_1)退一次流即可
      退流的过程是交替走匹配边/非匹配边,用floyd优化。
      若将(deg_i,deg_j)一起做,复杂度(sumlimits_{i,j}(deg_i+deg_j)^3=n^4)
      我们可以仅对(deg_j)做,对于两个点(x,y),令其匹配点为(x',y'),初始化(dis(x,y)=-w_{x,x'}+w_{y,x'})
      则对于退流的两个点(a,b),令(b)的匹配点为(b'),退流的流量为(dis_{a,b}-w_{b,b'})
      (sumlimits_{iin T'}deg_i^2frac{n}{deg_i}=O(n^3))
      放一份KM-bfs的板子
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define IL inline 
    typedef long long LL;
    
    const int N = 400 + 3;
    const int INF = 0x3f3f3f3f;
    
    struct Kuhn_Munkers {
    	int n;
    	int W[N][N];
    	int Lx[N],Ly[N];
    	int left[N];
    	int slack[N];
    	int pre[N];
    	bool T[N];
    	IL void init(int n) {
    		this->n = n;
    		for(int i=1;i<=n;i++) fill(W[i],W[i]+1+n,INF);
    	}
    	IL void bfs(int u) {
    		fill(slack,slack+1+n,INF);
    		fill(pre,pre+1+n,0);
    		int x,y=0,yy=0,a;
    		left[y] = u;
    		for(;;) {
    			x = left[y]; a = INF, T[y] = true;
    			for(int i=1;i<=n;i++) if(!T[i]){
    				if(slack[i] > Lx[x]+Ly[i]-W[x][i]) {
    					slack[i] = Lx[x] + Ly[i] - W[x][i];
    					pre[i] = y;
    				}
    				if(slack[i] < a) a = slack[i],yy = i;
    			}
    			for(int i=0;i<=n;i++) {
    				if(T[i]) { Lx[left[i]] -= a; Ly[i] += a;}
    				else slack[i] -= a;
    			}
    			y = yy;
    			if(!left[y]) break;
    		}
    		while(y) left[y] = left[pre[y]], y = pre[y];
    	}
    	IL int KM() {
    		fill(Lx,Lx+1+n,0);
    		fill(Ly,Ly+1+n,0);
    		fill(left,left+1+n,0);
    		for(int i=1;i<=n;i++) {
    			fill(T,T+1+n,false);
    			bfs(i);
    		}
    		int ans = 0LL;
    		for(int j=1;j<=n;j++) ans += W[left[j]][j];
    		return ans;
    	}
    }solver;
    
    
    int n;
    int p[N];
    LL a[N],b[N],c[N];
    
    int main() {
    	scanf("%d",&n); solver.init(n);
    	for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
    	for(int i=1;i<=n;i++) scanf("%d",&p[i]);
    	for(int i=1;i<=n;i++) scanf("%lld",&b[i]);
    	for(int i=1;i<=n;i++) scanf("%lld",&c[i]);
    	for(int i=1;i<=n;i++) {
    		for(int j=1;j<=n;j++) {
    			int v = 0;
    			for(int k=1;k<=n;k++) if(b[i]+c[j] > a[k]) v += p[k];
    			solver.W[i][j] = v;
    		}
    	}
    	printf("%d
    ",solver.KM());
    	return 0;
    }
    

    Disgusting Relationship

    • 题意:
      (n)置换环长为(i)的个数为(a_i)个,令(f(a_1,a_2,cdots,a_n))为环长为(i)的个数有(a_i)个的方案数
      给定(n,p)(p)为个数),求有多少个序列({a_i})使得(p)不整除(f(a))
    • 做法:
      (f(a)=dfrac{n!}{prodlimits_{i=1}^n i^{a_i}a_i!})
      题目可以转化为最大化分母中质因子(p)的次幂
      结论1:若(a_k>0(k>p))则不优
      (a_1=n),可得分母中质因子(p)的次幂最大为(sumlimits_{i=1}^{infty}frac{n}{p^i})
      (a_1=n-frac{n}{p} imes p,a_p=frac{n}{p}),此时次幂为(frac{n}{p}+sumlimits_{i=2}^{infty}frac{n}{p^i})
      结论2:令((a_1,a_2,cdots,a_m)_p=n)(a_i(i<m))上的每一个(1)要么在(a_1)要么在(a_p)(根据Kummer定理易证)
      (ans=p_{n\%p} imesprodlimits_{i=1}^{m-1}(b_i+1))(其中(p_i)(i)的分拆数方案数)

    Decrement on the Tree

    • 题意
      给定一棵带边权树,(m)次修改一条边的边权。对于一棵树,每次可以选择一条路径将其权值(-1),求最少多少次可以使树边权全为(0)
    • 做法
      对于一个点,其边可以两两配对
      令边权和为(sum),最大边权为(mx),若(mx>sum-mx),贡献为(2mx-sum)。若(mxle sum-mx),若为奇数贡献为(1),否则为(0)
  • 相关阅读:
    设计模式~门面模式
    设计模式~享元模式
    设计模式~代理模式
    Java IO流:(六)节点流(文件流)之 FileWriter
    Java IO流:(五)节点流(文件流)之 FileReader
    Java IO流:(四)节点流(文件流)
    Java IO流:(三)IO流四大基类
    Java IO流:(二)IO流原理及流的分类
    Java IO流:(一)File 文件类
    每周总结
  • 原文地址:https://www.cnblogs.com/Grice/p/13833667.html
Copyright © 2020-2023  润新知