• 21牛客多校第九场


    A

    [sumlimits_{i=0}^{n}sumlimits_{1le cjle ai+b}i^pj^q=sumlimits_{i=0}^{n}sumlimits_{j=1}^{lfloor frac{ai+b}{c} floor}i^pj^q ]

    (F(n)=sumlimits_{i=0}^ni^q),有(F(n))是关于(n)(q+1)次多项式,设(i)次项系数为(G[q][i])

    (G)可以通过伯努利数求得,令(S_t(n)=sum_{i=0}^{n-1}i^t),有(S_t(n)=frac{1}{t+1}sumlimits_{i=0}^tinom{t+1}{i}B_in^{t+1-i})

    由伯努利数的递推式(B_t=-frac{1}{t+1}sumlimits_{i=0}^{t-1}inom{t+1}{i}B_i)求出伯努利数之后即得到(G)

    (G)相较于(S_t(n))仅多了(n^t)一项,该位系数(+1)即可

    则原式为(sumlimits_{t=1}^{q+1}G_tsumlimits_{i=0}^{n}i^plfloor frac{ai+b}{c} floor^t),后面为类欧几里得板子(这个(G)系数三角本身类欧板子也需要


    类欧几里得是用来解决如下的问题:

    [F(n,a,b,c,k_1,k_2)=sumlimits_{x=0}^{n}x^{k_1}lfloor frac{ax+b}{c} floor^{k_2} ]

    对于边界情况(a=0||k_2=0)显然可以通过预处理出的系数直接求解

    对于(age c|| bge c)的情况,可以将(a)拆为(p+A,p=lfloorfrac{a}{c} floor,A=a mod c),同理将(b)拆为(q+B),有:

    [egin{aligned} F(n,a,b,c,k_1,k_2)&=sumlimits_{x=0}^{n}x^{k_1}lfloor frac{ax+b}{c} floor^{k_2}\ &=sumlimits_{x=0}^nx^{k_1}(px+q+lfloor frac{Ax+B}{c} floor)^{k_2}\ &=sumlimits_{x=0}^nx^{k_1}sumlimits_{i+j+k=k2}(px)^iq^j(lfloor frac{Ax+B}{c} floor)^{k}\ &=sumlimits_{i+j+k=k2}p^iq^jsumlimits_{x=0}^nx^{k_1+i}(lfloor frac{Ax+B}{c} floor)^{k}\ &=sumlimits_{i=0}^{k_2}sumlimits_{j=0}^{k_2-i}p^iq^jsumlimits_{x=0}^nx^{k_1+i}(lfloor frac{Ax+B}{c} floor)^{k_2-i-j}\ &=sumlimits_{i=0}^{k_2}sumlimits_{j=0}^{k_2-i}p^iq^jF(n,A,B,c,k_1+i,k_2-i-j) end{aligned} ]

    枚举(i,j)后仍为递归形式

    而当(a,b<c)时,有(lfloor frac{a(x+1)+b}{c} floor-lfloor frac{ax+b}{c} floorle 1)因此(lfloor frac{ax+b}{c} floor)存在上界(m=lfloor frac{an+b}{c} floor),有:

    [egin{aligned} F(n,a,b,c,k_1,k_2)&=sumlimits_{x=0}^{n}x^{k_1}lfloor frac{ax+b}{c} floor^{k_2}\ &=sumlimits_{x=0}^{n}x^{k_1}(sumlimits_{w=0}^{m-1}left [ lfloor frac{ax+b}{c} floor>w ight])^{k_2} end{aligned} ]

    差分一下有:

    [F(n,a,b,c,k_1,k_2)=sumlimits_{x=0}^{n}x^{k_1}sumlimits_{w=0}^{m-1}left[lfloor frac{ax+b}{c} floor>w ight]left((w+1)^{k_2}-w^{k_2} ight) ]

    (lfloor frac{ax+b}{c} floor>w)变形得:

    (lfloor frac{ax+b}{c} floorge w+1Leftrightarrow ax+bge c(w+1)Leftrightarrow ax>cw+c-b-1Leftrightarrow x>lfloorfrac{cw+c-b-1}{a} floor)

    原式即为:

    [egin{aligned} F(n,a,b,c,k_1,k_2)&=sumlimits_{x=0}^{n}x^{k_1}sumlimits_{w=0}^{m-1}left[x>lfloorfrac{cw+c-b-1}{a} floor ight]left((w+1)^{k_2}-w^{k_2} ight)\ &=sumlimits_{w=0}^{m-1}left((w+1)^{k_2}-w^{k_2} ight)sumlimits_{x=0}^{n}x^{k_1}left[x>lfloorfrac{cw+c-b-1}{a} floor ight]\ &=sumlimits_{w=0}^{m-1}left((w+1)^{k_2}-w^{k_2} ight)sumlimits_{x=0}^{n}x^{k_1}-sumlimits_{w=0}^{m-1}left((w+1)^{k_2}-w^{k_2} ight)sumlimits_{x=0}^{lfloorfrac{cw+c-b-1}{a} floor}x^{k_1}\ &=m^{k_2}sumlimits_{x=0}^{n}x^{k_1}-sumlimits_{w=0}^{m-1}left((w+1)^{k_2}-w^{k_2} ight)sumlimits_{x=0}^{lfloorfrac{cw+c-b-1}{a} floor}x^{k_1} end{aligned} ]

    其中(k_1)次幂和可以通过预处理(G)转化为多项式,前面容易处理,考虑后面一项,令(lfloorfrac{cw+c-b-1}{a} floor=h)

    [egin{aligned} &sumlimits_{w=0}^{m-1}left((w+1)^{k_2}-w^{k_2} ight)sumlimits_{x=0}^{lfloorfrac{cw+c-b-1}{a} floor}x^{k_1}\ =&sumlimits_{w=0}^{m-1}left((w+1)^{k_2}-w^{k_2} ight)sumlimits_{j=0}^{k_1+1}G[k_1][j] h^j\ =&sumlimits_{w=0}^{m-1}sumlimits_{i=0}^{k_2-1}inom{k_2}{i}w^isumlimits_{j=0}^{k_1+1}G[k_1][j] h^j\ =&sumlimits_{i=0}^{k_2-1}sumlimits_{j=0}^{k_1+1}inom{k_2}{i}G[k_1][j]sumlimits_{w=0}^{m-1}w^ih^j\ =&sumlimits_{i=0}^{k_2-1}sumlimits_{j=0}^{k_1+1}inom{k_2}{i}G[k_1][j]sumlimits_{w=0}^{m-1}w^ileft(lfloorfrac{cw+c-b-1}{a} floor ight)^j\ =&sumlimits_{i=0}^{k_2-1}sumlimits_{j=0}^{k_1+1}inom{k_2}{i}G[k_1][j]cdot F(m-1,c,c-b-1,a,i,j) end{aligned} ]

    同样为一个递归形式,由此即可写出整个类欧几里得模板

    (由于(a,c)两项在不断的进行取模和交换,与辗转相除法十分类似,复杂度有所保证

    同时过程中可以使用记忆化搜索优化

    #include<bits/stdc++.h>
    #define inf 2139062143
    #define ll long long
    #define db double
    #define ld long double
    #define ull unsigned long long
    #define MAXN 1001001
    #define MOD 998244353
    #define Fill(a,x) memset(a,x,sizeof(a))
    #define rep(i,s,t) for(int i=(s),i##end=(t);i<=i##end;++i)
    #define dwn(i,s,t) for(int i=(s),i##end=(t);i>=i##end;--i)
    #define ren for(int i=fst[x];i;i=nxt[i])
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define pb push_back
    using namespace std;
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
        while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    namespace CALC
    {
    	inline int pls(int a,int b){return a+b>=MOD?a+b-MOD:(a+b<0?a+b+MOD:a+b);}
    	inline int mns(int a,int b){return a-b<0?a-b+MOD:(a-b>=MOD?a-b-MOD:a-b);}
    	inline int mul(int a,int b){return (1LL*a*b)%MOD;}
    	inline void inc(int &a,int b){a=pls(a,b);}
    	inline void dec(int &a,int b){a=mns(a,b);}
    	inline void tms(int &a,int b){a=mul(a,b);}
    	inline int qp(int x,int t,int res=1)
    		{for(;t;t>>=1,x=mul(x,x)) if(t&1) res=mul(res,x);return res;}
    	inline int Inv(int x){return qp(x,MOD-2);}
    }
    using namespace CALC;
    int n,C[210][210],B[210],G[210][210],fac[210],ifac[210],ans;
    void mem(int n=205)
    {
    	rep(i,0,n) {C[i][0]=1;rep(j,1,i) C[i][j]=pls(C[i-1][j-1],C[i-1][j]);}
    	fac[0]=ifac[0]=B[0]=1;int tmp;
    	rep(i,1,n)
    	{
    		tmp=0;rep(j,0,i-1) tmp=pls(tmp,mul(C[i+1][j],B[j]));
    		tmp=mns(0,tmp),B[i]=mul(tmp,Inv(i+1));
    		fac[i]=mul(fac[i-1],i),ifac[i]=Inv(fac[i]);
    	}
    	rep(i,0,n)
    	{
    		tmp=Inv(i+1);
    		rep(j,0,i) G[i][i+1-j]=mul(mul(tmp,C[i+1][j]),B[j]);
    		inc(G[i][i],1);
    	}
    }
    inline int calc(int n,int m)
    {
    	int res=0,pw=1;
    	rep(i,0,m+1) inc(res,mul(G[m][i],pw)),tms(pw,n);
    	return res;
    }
    int res[210][210][210];
    int F(ll n,int a,int b,int c,int k1,int k2,int dep=0)
    {
    	if(~res[k1][k2][dep]) return res[k1][k2][dep];
    	int &sum=res[k1][k2][dep]=0;
    	if(!k2||!a) return sum=mul(calc(n,k1),qp(b/c,k2));
    	if(a>=c||b>=c)
    	{
    		int p=a/c,q=b/c;
    		for(int i=0,p1=1;i<=k2;i++,tms(p1,p))
    			for(int j=0,p2=1;j<=k2-i;j++,tms(p2,q))
    				inc(sum,mul(mul(mul(p1,p2),mul(mul(ifac[i],ifac[j]),mul(ifac[k2-i-j],fac[k2]))),
    				F(n,a%c,b%c,c,k1+i,k2-i-j,dep+1)));
    		return sum;
    	}
    	ll m=(n*a+b)/c;sum=mul(qp(m,k2),calc(n,k1));
    	rep(i,0,k2-1) rep(j,0,k1+1)
    		dec(sum,mul(mul(C[k2][i],G[k1][j]),F(m-1,c,c-b-1,a,i,j,dep+1)));
    	return sum;
    }
    int main()
    {
    	mem();Fill(res,0xff);
    	int a=read(),b=read(),c=read(),k1=read(),k2=read(),n=read();
    	rep(i,1,k2+1) inc(ans,mul(G[k2][i],F(n,a,b,c,k1,i)));
    	printf("%d
    ",ans);
    }
    

    B

    很玄的图论题 咕

    C

    (LGV)引理可知本题答案为

    [egin{vmatrix} inom{a_1+1}{1}&inom{a_1+2}{2}&cdots &inom{a_1+n}{n}\ inom{a_2+1}{1}&inom{a_2+2}{2}&cdots &inom{a_2+n}{n}\ vdots&vdots&ddots&vdots\ inom{a_n+1}{1}&inom{a_n+2}{2}&cdots &inom{a_n+n}{n} end{vmatrix} =prodlimits_{i=1}^nfrac{1}{i!}egin{vmatrix} a_1+1&(a_1+1)(a_1+2)&cdots &(a_1+1)cdot cdots cdot(a_1+n)\ a_2+1&(a_2+1)(a_2+2)&cdots &(a_2+1)cdot cdots cdot(a_2+n)\ vdots&vdots&ddots&vdots\ a_n+1&(a_n+1)(a_n+2)&cdots &(a_n+1)cdot cdots cdot(a_n+n)\ end{vmatrix} ]

    可以都用第(i)列将(i+1)列中(a_x+y)的最大(y)这一项消掉,最终得到答案为

    [prodlimits_{i=1}^nfrac{1}{i!}egin{vmatrix} a_1+1&(a_1+1)^2&cdots &(a_1+1)^n\ a_2+1&(a_2+1)^2&cdots &(a_2+1)^n\ vdots&vdots&ddots&vdots\ a_n+1&(a_n+1)^2&cdots &(a_n+1)^n end{vmatrix}=prodlimits_{i=1}^nfrac{a_i+1}{i!}egin{vmatrix} 1&(a_1+1)^1&cdots &(a_1+1)^{n-1}\ 1&(a_2+1)^1&cdots &(a_2+1)^{n-1}\ vdots&vdots&ddots&vdots\ 1&(a_n+1)^1&cdots &(a_n+1)^{n-1} end{vmatrix} ]

    该行列式为范德蒙德行列式,即(ans=prodlimits_{i=1}^nfrac{a_i+1}{i!}prodlimits_{1le j<ile n}a_i-a_j)

    后半部分可以通过卷积求出所有差的出现次数得到答案

    #include<bits/stdc++.h>
    #define inf 2139062143
    #define ll long long
    #define db double
    #define ld long double
    #define ull unsigned long long
    #define MAXN 2001001
    #define MOD 998244353
    #define Fill(a,x) memset(a,x,sizeof(a))
    #define rep(i,s,t) for(int i=(s),i##end=(t);i<=i##end;++i)
    #define dwn(i,s,t) for(int i=(s),i##end=(t);i>=i##end;--i)
    #define ren for(int i=fst[x];i;i=nxt[i])
    #define pls(a,b) (a+b)%MOD
    #define mns(a,b) (a-b+MOD)%MOD
    #define mul(a,b) (1LL*(a)*(b))%MOD
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define pb push_back
    using namespace std;
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
        while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    int n,a[MAXN<<1],b[MAXN<<1],ifac[MAXN];
    int rev[MAXN<<1],lim,lg,pw[30],ipw[30],ans=1;
    int qp(int bas,int t,int res=1)
    {
        for(;t;t>>=1,bas=mul(bas,bas)) if(t&1) res=mul(res,bas);return res;
    }
    #define inv(x) qp(x,MOD-2)
    void ntt(int *a,int n,int f)
    {
        rep(i,0,n-1) if(i<rev[i]) swap(a[i],a[rev[i]]);
        for(int i=1,t=1;i<n;i<<=1,++t)
        {
            int wn= f>0?pw[t]:ipw[t];for(int j=0;j<n;j+=i<<1)
            {
                int w=1,x,y;for(int k=0;k<i;++k,w=mul(w,wn))
                    x=a[j+k],y=mul(a[j+k+i],w),a[j+k]=pls(x,y),a[j+k+i]=mns(x,y);
            }
        }
        if(f>0) return ;int nv=inv(n);rep(i,0,n-1) a[i]=mul(a[i],nv);
    }
    int main()
    {
    	n=read();a[0]++;rep(i,1,n) a[read()+1]++;ifac[0]=1;
    	rep(i,1,n) ifac[i]=mul(ifac[i-1],inv(i)),ans=mul(ans,ifac[i]);
    	n=1000005;rep(i,0,n) b[i]=a[n-i];
        for(lim=1,lg=1;lim<=(n+1<<1);lim<<=1,lg++)
            pw[lg]=qp(3,(MOD-1)/(1<<lg)),ipw[lg]=inv(pw[lg]);
        rep(i,1,lim-1) rev[i]=(rev[i>>1]>>1)|((i&1)<<lg-2);
        ntt(a,lim,1);ntt(b,lim,1);rep(i,0,lim-1) a[i]=mul(a[i],b[i]);ntt(a,lim,-1);
        rep(i,n+1,n<<1) if(a[i]) ans=mul(ans,qp(i-n,a[i]));
        printf("%d
    ",ans);
    }
    

    D

    奇怪构造题 咕

    E

    由于从根开始的路径温度是递减的

    因此只需要找到每个查询点向上最高满足限制的祖先,并在这个祖先的子树里查询(t_ige l)的点的个数即可

    前者可以用倍增简单实现,后者可以对(dfs)序维护主席树实现

    #include<bits/stdc++.h>
    #define inf 2139062143
    #define ll long long
    #define db double
    #define ld long double
    #define ull unsigned long long
    #define MAXN 100100
    #define MOD 998244353
    #define Fill(a,x) memset(a,x,sizeof(a))
    #define rep(i,s,t) for(int i=(s),i##end=(t);i<=i##end;++i)
    #define dwn(i,s,t) for(int i=(s),i##end=(t);i>=i##end;--i)
    #define ren for(int i=fst[x];i;i=nxt[i])
    #define pls(a,b) (a+b)%MOD
    #define mns(a,b) (a-(b))%MOD
    #define mul(a,b) (1LL*(a)*(b))%MOD
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define pb push_back
    using namespace std;
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
        while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    const int lim=1e9;
    int n,h[MAXN],g[MAXN],q,nxt[MAXN<<1],to[MAXN<<1],fst[MAXN],cnt;
    int hsh[MAXN],dfn,in[MAXN],ou[MAXN],tt;
    int rt[MAXN],w[MAXN<<7],ls[MAXN<<7],rs[MAXN<<7],tot,fa[MAXN][21];
    void add(int u,int v) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v;}
    void mdf(int &k,int kk,int l,int r,int x)
    {
    	w[k=++tot]=w[kk]+1,ls[k]=ls[kk],rs[k]=rs[kk];
    	if(l==r) return ;int mid=l+r>>1;
    	x<=mid?mdf(ls[k],ls[kk],l,mid,x):mdf(rs[k],rs[kk],mid+1,r,x);
    }
    int query(int k,int kk,int l,int r,int x)
    {
    	if(!k) return 0LL;if(l==r) return w[k]-w[kk];int mid=l+r>>1;
    	if(x>mid) return query(rs[k],rs[kk],mid+1,r,x);
    	else return w[rs[k]]-w[rs[kk]]+query(ls[k],ls[kk],l,mid,x);
    }
    void dfs(int x,int pa)
    {
    	fa[x][0]=pa,in[x]=++dfn,hsh[dfn]=x;ren if(to[i]^pa)
    		dfs(to[i],x);ou[x]=dfn;
    }
    int main()
    {
    	n=read();int a,b,x,z;rep(i,2,n) a=read(),b=read(),add(a,b),add(b,a);
    	rep(i,1,n) g[i]=read();
    	dfs(1,1);
    	rep(j,1,20) rep(i,1,n)
    		fa[i][j]=fa[fa[i][j-1]][j-1];
    	rep(i,1,n) mdf(rt[i],rt[i-1],1,lim,g[hsh[i]]);
    	rep(Q,1,read())
    	{
    		z=x=read(),a=read(),b=read();
    		if(g[x]>b||g[x]<a) {puts("0");continue;}
    		dwn(j,20,0) if(g[fa[z][j]]<=b) z=fa[z][j];
    		printf("%d
    ",query(rt[ou[z]],rt[in[z]-1],1,lim,a));
    	}
    }
    

    F

    很猛的dp 咕

    G

    可做树(dp)

    H

    对于位数相同的所有数,答案即为三进制分解

    预处理位数(le i)的数共有多少个即可

    #include<bits/stdc++.h>
    #define inf 2139062143
    #define ll long long
    #define db double
    #define ld long double
    #define ull unsigned long long
    #define MAXN 100100
    #define MOD 998244353
    #define Fill(a,x) memset(a,x,sizeof(a))
    #define rep(i,s,t) for(int i=(s),i##end=(t);i<=i##end;++i)
    #define dwn(i,s,t) for(int i=(s),i##end=(t);i>=i##end;--i)
    #define ren for(int i=fst[x];i;i=nxt[i])
    #define pls(a,b) (a+b)%MOD
    #define mns(a,b) (a-(b))%MOD
    #define mul(a,b) (1LL*(a)*(b))%MOD
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define pb push_back
    using namespace std;
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
        while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    int n,m,g[30];
    ll pw[30],sum[30];
    int main()
    {
    	n=read()-1;pw[0]=1;rep(i,1,29) pw[i]=pw[i-1]*3,sum[i]=sum[i-1]+pw[i];
    	int pos=upper_bound(sum+1,sum+30,n)-sum-1;n-=sum[pos];
    	rep(i,1,pos+1) g[++m]=n%3,n/=3;
    	dwn(i,m,1)
    		if(g[i]==0) cout<<2;
    		else if(g[i]==1) cout<<3;
    		else cout<<6;
    }
    

    I

    奇妙式子题 咕

    J

    右转显然和任何都不冲突,可以拿出来,而剩下的八种情况中每天至多同时存在两种,连边如下,答案为总和-最大匹配:

    image

    黑白染色之后发现同色点间仅((1,6),(2,5))之间存在边,因此可以暴力枚举这两条边的匹配,然后剩下的跑二分图匹配

    #include<bits/stdc++.h>
    #define inf 2139062143
    #define ll long long
    #define db double
    #define ld long double
    #define ull unsigned long long
    #define MAXN 15
    #define MAXM 30
    #define MOD 998244353
    #define Fill(a,x) memset(a,x,sizeof(a))
    #define rep(i,s,t) for(int i=(s),i##end=(t);i<=i##end;++i)
    #define dwn(i,s,t) for(int i=(s),i##end=(t);i>=i##end;--i)
    #define ren for(int i=fst[x];i;i=nxt[i])
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define pb push_back
    using namespace std;
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
        while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    namespace CALC
    {
    	inline int pls(int a,int b){return a+b>=MOD?a+b-MOD:(a+b<0?a+b+MOD:a+b);}
    	inline int mns(int a,int b){return a-b<0?a-b+MOD:(a-b>=MOD?a-b-MOD:a-b);}
    	inline int mul(int a,int b){return (1LL*a*b)%MOD;}
    	inline void inc(int &a,int b){a=pls(a,b);}
    	inline void dec(int &a,int b){a=mns(a,b);}
    	inline void tms(int &a,int b){a=mul(a,b);}
    	inline int qp(int x,int t,int res=1)
    		{for(;t;t>>=1,x=mul(x,x)) if(t&1) res=mul(res,x);return res;}
    	inline int Inv(int x){return qp(x,MOD-2);}
    }
    using namespace CALC;
    struct Dinic
    {
        int fst[MAXN],nxt[MAXM<<1],to[MAXM<<1],cnt,val[MAXM<<1];
        int vis[MAXN],q[MAXN],l,r,S,T,tot,dis[MAXN],cur[MAXN];
        void mem(){Fill(fst,0);cnt=1,tot=0;}
        void add(int u,int v,int w) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v,val[cnt]=w;}
        void ins(int u,int v,int w) {add(u,v,w);add(v,u,0);}
        int bfs()
        {
            vis[T]=++tot,dis[T]=0,q[l=r=1]=T;memcpy(cur,fst,sizeof(cur));
            int x;while(l<=r)
            {
                x=q[l++];ren if(val[i^1]&&vis[to[i]]!=tot)
                    dis[to[i]]=dis[x]+1,vis[to[i]]=tot,q[++r]=to[i];
            }
            return vis[S]==tot;
        }
        int dfs(int x,int a)
        {
            if(x==T||!a) return a;int flw=0,f;
            for(int& i=cur[x];i&&a;i=nxt[i])
                if(val[i]&&dis[to[i]]==dis[x]-1&&(f=dfs(to[i],min(a,val[i]))))
                    val[i]-=f,val[i^1]+=f,a-=f,flw+=f;
            return flw;
        }
        int solve(int ss,int tt,int res=0)
            {S=ss,T=tt;while(bfs()) res+=dfs(S,inf);return res;}
    }D;
    const int ln[]={0,2,5,7},rn[]={1,3,4,6};
    int n,a[5][5],bas,ans,g[8],sum,res;
    int main()
    {
    	int s=8,t=9;rep(T,1,read())
    	{
    		rep(i,0,3) rep(j,0,3) a[i][j]=read();
    		bas=sum=ans=0;rep(i,0,3) bas=max(bas,a[i][(i+3)%4]);
    		rep(i,0,3) g[i<<1]=a[i][(i+2)%4],g[i<<1|1]=a[i][(i+1)%4];
    		rep(i,0,7) sum+=g[i];
    		rep(x,0,min(g[1],g[6])) rep(y,0,min(g[2],g[5]))
    		{
    			D.mem();
    			g[1]-=x,g[6]-=x,g[2]-=y,g[5]-=y;
    			rep(i,0,3)
    			{
    				if(g[ln[i]]) D.ins(s,ln[i],g[ln[i]]);
    				if(g[rn[i]]) D.ins(rn[i],t,g[rn[i]]);
    			}
    			D.ins(0,1,inf),D.ins(0,3,inf),D.ins(0,4,inf);
    			D.ins(2,3,inf),D.ins(2,6,inf);
    			D.ins(5,1,inf),D.ins(5,4,inf);
    			D.ins(7,3,inf),D.ins(7,4,inf),D.ins(7,6,inf);
    			res=D.solve(s,t),ans=max(ans,x+y+res);
    			g[1]+=x,g[6]+=x,g[2]+=y,g[5]+=y;
    		}
    		ans=max(sum-ans,bas);
    		printf("%d
    ",ans);
    	}
    }
    
  • 相关阅读:
    Allegro PCB转换成PADS方法
    Altium Designer只显示某一层,隐藏其他层
    DCDC功率电感(Inductor)选型
    DDR布线教程
    DDR地址、容量计算、Bank理解
    DDR3中的ODT(On-die termination)
    LINUX文件系统操作指令之四
    linux系统之间通过nfs网络文件系统挂载设置方法
    linux消息队列编程实例
    system()函数
  • 原文地址:https://www.cnblogs.com/yyc-jack-0920/p/15149999.html
Copyright © 2020-2023  润新知