题解 [LNOI2022] 盒

传送门

答案是

\[\sum\limits_{i=0}^{n-1}w_i\sum\limits_{j=0}^{s_i}|s_i-j|\binom{i+j-1}{j}\binom{n−i+S−j-1}{n-i-1} \]

然后照着题解推式子

  • \(j\binom{i+j-1}{j}=i\binom{i+j-1}{j-1}\),用于在求和式中将变量系数化为不变量系数提到外面
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 3000010
#define ll long long
//#define int long long

char buf[1<<21], *p1=buf, *p2=buf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
inline int read() {
	int ans=0, f=1; char c=getchar();
	while (!isdigit(c)) {if (c=='-') f=-f; c=getchar();}
	while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
	return ans*f;
}

int n;
int a[N];
const ll mod=998244353;
ll w[N], fac[N], inv[N];

namespace force{
	bool vis[N];
	ll dis[N], ans;
	int b[N], inc[N], back[N], sum;
	int head[N], ecnt, s, t, tot;
	struct edge{int to, next, flw; ll cst;}e[N<<1];
	inline void add(int s, int t, int f, ll c) {e[++ecnt]={t, head[s], f, c}; head[s]=ecnt;}
	bool spfa(int s, int t) {
		for (int i=1; i<=tot; ++i) dis[i]=INF, back[i]=-1;
		queue<int> q;
		dis[s]=0; inc[s]=INF;
		q.push(s);
		while (q.size()) {
			int u=q.front(); q.pop();
			vis[u]=0;
			for (int i=head[u],v; ~i; i=e[i].next) {
				v = e[i].to;
				if (e[i].flw && dis[v]>dis[u]+e[i].cst) {
					dis[v]=dis[u]+e[i].cst;
					back[v]=i; inc[v]=min(inc[u], e[i].flw);
					if (!vis[v]) vis[v]=1, q.push(v);
				}
			}
		}
		return ~back[t];
	}
	void calc() {
		ecnt=1; tot=n+2;
		for (int i=1; i<=n+2; ++i) head[i]=-1;
		s=n+1; t=n+2;
		for (int i=1; i<=n; ++i) add(s, i, a[i], 0), add(i, s, 0, 0);
		for (int i=1; i<=n; ++i) add(i, t, b[i], 0), add(t, i, 0, 0);
		for (int i=2; i<=n; ++i) add(i, i-1, INF, w[i-1]), add(i-1, i, 0, -w[i-1]);
		for (int i=1; i<n; ++i) add(i, i+1, INF, w[i]), add(i+1, i, 0, -w[i]);
		ll ans=0;
		int tem=0;
		while (spfa(s, t)) {
			tem+=inc[t];
			ans=(ans+inc[t]*dis[t])%mod;
			for (int u=t; u!=s; u=e[back[u]^1].to) {
				e[back[u]].flw-=inc[t];
				e[back[u]^1].flw+=inc[t];
			}
		}
		// cout<<tem<<endl;
		force::ans=(force::ans+ans)%mod;
	}
	void dfs(int u, int rest) {
		if (u>n) {if (!rest) calc(); return ;}
		for (int i=0; i<=rest; ++i) b[u]=i, dfs(u+1, rest-i);
	}
	void solve() {
		ans=sum=0;
		for (int i=1; i<=n; ++i) sum+=a[i];
		dfs(1, sum);
		printf("%lld\n", ans);
	}
}

namespace task{
	ll ans;
	int sum[N], lim;
	inline ll C(int n, int k) {return n<k?0:fac[n]*inv[k]%mod*inv[n-k]%mod;}
	struct func{
		ll val;
		int n, m, p, q;
		void init(int a, int b) {n=a; m=b; p=q=0; val=C(n+m-1, m);}
		void upd(int x, int y) {
			while (p<x) ++p, val=(val-C(p+q, q)*C(n-p+m-q-1, n-p))%mod;
			while (q<y) ++q, val=(val+C(p+q, q)*C(n-p+m-q-1, m-q))%mod;
		}
	}f1, f2;
	ll qval(int n, int m, int p, int q) {
		ll ans=0;
		for (int i=0; i<=q; ++i) ans=(ans+C(p+i, p)*C(n-p+m-i-1, m-i))%mod;
		return ans;
	}
	void solve() {
		for (int i=1; i<=n; ++i) sum[i]=sum[i-1]+a[i];
		lim=n+sum[n]; ans=0;
		f1.init(n-1, sum[n]); f2.init(n, sum[n]-1);
		for (int i=1; i<n; ++i) {
			ll tem=0;
			// for (int j=0; j<=sum[i]; ++j) tem=(tem+2ll*sum[i]*C(i+j-1, j)%mod*C(n-i+sum[n]-j-1, sum[n]-j))%mod;
			// tem=(tem+2ll*sum[i]*qval(n-1, sum[n], i-1, sum[i]))%mod;
			f1.upd(i-1, sum[i]), tem=(tem+2ll*sum[i]*f1.val)%mod;
			// for (int j=0; j<=sum[i]-1; ++j) tem=(tem-2ll*i*C(i+j, j)%mod*C(n-i+sum[n]-j-2, sum[n]-j-1))%mod;
			// tem=(tem-2ll*i*qval(n, sum[n]-1, i, sum[i]-1))%mod;
			if (sum[i]) f2.upd(i, sum[i]-1), tem=(tem-2ll*i*f2.val)%mod;
			tem=(tem+i*C(n+sum[n]-1, n)-sum[i]*C(n+sum[n]-1, sum[n]))%mod;
			ans=(ans+w[i]*tem)%mod;
		}
		printf("%lld\n", (ans%mod+mod)%mod);
	}
}

signed main()
{
	// freopen("box.in", "r", stdin);
	// freopen("box.out", "w", stdout);

	int T=read();
	fac[0]=fac[1]=1; inv[0]=inv[1]=1;
	for (int i=2; i<N; ++i) fac[i]=fac[i-1]*i%mod;
	for (int i=2; i<N; ++i) inv[i]=(mod-mod/i)*inv[mod%i]%mod;
	for (int i=2; i<N; ++i) inv[i]=inv[i-1]*inv[i]%mod;
	while (T--) {
		n=read();
		for (int i=1; i<=n; ++i) a[i]=read();
		for (int i=1; i<n; ++i) w[i]=read();
		// force::solve();
		task::solve();
	}

	return 0;
}
posted @ 2022-06-08 08:55  Administrator-09  阅读(4)  评论(0编辑  收藏  举报