题解 表格

传送门

推出来柿子了,但不会展开,就挂了

  • 一个 \(n\) 次多项式的前缀和是 \(n+1\) 次多项式
  • 当发现一个柿子不会展开时,可以先大致确定它是几次多项式,然后直接高斯消元出系数

然后这题就没了
正解好像是拉格朗日插值,先咕了

Code:
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 100010
#define ll long long
#define reg register int
#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;
}

ll n, m, l, r;
const ll mod=1e9+7;

namespace force{
	int ans;
	void solve() {
		for (int x1=1; x1<=n; ++x1) 
			for (int x2=x1+1; x2<=n; ++x2) if (x2!=x1)
				for (int x3=x2+1; x3<=n; ++x3) if (x3!=x1 && x3!=x2) 
					for (int y1=1; y1<=m; ++y1) 
						for (int y2=1; y2<=m; ++y2) if (y2!=y1) 
							for (int y3=1; y3<=m; ++y3) if (y3!=y2 && y3!=y1) {
								int dis=abs(x1-x2)+abs(y1-y2)+abs(x2-x3)+abs(y2-y3)+abs(x1-x3)+abs(y1-y3);
								if (l<=dis && dis<=r) {
									++ans;
									// cout<<x1<<' '<<y1<<' '<<x2<<' '<<y2<<' '<<x3<<' '<<y3<<endl;
								}
							}
		printf("%lld\n", ans%mod);
		exit(0);
	}
}

namespace task1{
	ll fac[N], inv[N], ans;
	inline ll C(int n, int k) {return fac[n]*inv[k]%mod*inv[n-k]%mod;}
	void solve() {
		int lim=max(n, m);
		fac[0]=fac[1]=1; inv[0]=inv[1]=1;
		for (int i=2; i<=lim; ++i) fac[i]=fac[i-1]*i%mod;
		for (int i=2; i<=lim; ++i) inv[i]=(mod-mod/i)*inv[mod%i]%mod;
		for (int i=2; i<=lim; ++i) inv[i]=inv[i-1]*inv[i]%mod;
		for (int i=3; i<=n; ++i)
			for (int j=3; j<=m; ++j)
				if (l<=(i+j-2)*2 && (i+j-2)*2<=r)
					ans=(ans+(n-i+1ll)*(m-j+1ll)%mod*(i-2ll)%mod*(j-2ll)%mod*fac[3]%mod)%mod;
		printf("%lld\n", ans);
		exit(0);
	}
}

namespace task2{
	ll fac[N], inv[N], inv2[N];
	ll ans;
	// inline ll C(int n, int k) {return fac[n]*inv2[k]%mod*inv2[n-k]%mod;}
	inline ll sum2(ll k) {return k*(k+1)%mod*(2ll*k+1)%mod*inv[6]%mod;}
	inline ll sum(ll k) {return k*(k+1)%mod*inv[2]%mod;}
	void solve() {
		// int lim=max(max(n, m), 10ll);
		int lim=10;
		fac[0]=fac[1]=1; inv[0]=inv[1]=1; inv2[0]=inv2[1]=1;
		for (int i=2; i<=lim; ++i) fac[i]=fac[i-1]*i%mod;
		for (int i=2; i<=lim; ++i) inv[i]=(mod-mod/i)*inv[mod%i]%mod;
		for (int i=2; i<=lim; ++i) inv2[i]=inv2[i-1]*inv[i]%mod;
		for (int i=3; i<=n; ++i) {
			ll L=max(3ll, (l-2*i+5ll)/2ll), R=min(m, (r-2ll*i+4ll)/2ll);
			if (L<=R) ans = (ans+1ll*(n-i+1ll)*(i-2ll)%mod * (( -(sum2(R)-sum2(L-1)) + (sum(R)-sum(L-1))%mod*(m+3)%mod - (2ll*m+2)*(R-L+1ll)%mod )%mod)%mod)%mod;
		}
		// for (int i=3; i<=n; ++i) {
			// cout<<"i: "<<i<<' '<<max(3, (l-2*i+5)/2)<<' '<<min(m, (r-2*i+4)/2)<<endl;
		// }
		ans = ans*fac[3]%mod;
		printf("%lld\n", (ans%mod+mod)%mod);
		exit(0);
	}
}

namespace task3{
	ll fac[N], inv[N], ans;
	inline ll C(int n, int k) {return fac[n]*inv[k]%mod*inv[n-k]%mod;}
	void solve() {
		int lim=max(max(n, m), 10ll);
		fac[0]=fac[1]=1; inv[0]=inv[1]=1;
		for (int i=2; i<=lim; ++i) fac[i]=fac[i-1]*i%mod;
		for (int i=2; i<=lim; ++i) inv[i]=(mod-mod/i)*inv[mod%i]%mod;
		for (int i=2; i<=lim; ++i) inv[i]=inv[i-1]*inv[i]%mod;
		for (int i=3; i<=n; ++i)
			for (int j=max(3ll, (l-2*i+5)/2),ends=min(m, (r-2*i+4)/2); j<=ends; ++j) 
				ans=(ans+(n-i+1ll)*(m-j+1ll)%mod*(i-2ll)%mod*(j-2ll)%mod*fac[3]%mod)%mod;
		// for (int i=3; i<=n; ++i) {
			// cout<<"i: "<<i<<' '<<max(3, (l-2*i+5)/2)<<' '<<min(m, (r-2*i+4)/2)<<endl;
		// }
		printf("%lld\n", ans);
		exit(0);
	}
}

namespace task{
	ll fac[N], inv[N], inv2[N], k[10], Gm, r;
	inline ll sum2(ll k) {k%=mod; return k*(k+1)%mod*(2ll*k%mod+1)%mod*inv[6]%mod;}
	inline ll sum(ll k) {k%=mod; return k*(k+1)%mod*inv[2]%mod;}
	inline ll G(ll k) {return (-(sum2(k)-5ll)+(sum(k)-3ll)%mod*(m%mod+3ll)%mod-(2ll*m%mod+2ll)*(k%mod-2ll)%mod)%mod;}
	inline ll H1(ll base) {base%=mod; ll ans=0ll,t=1ll; for (int i=1; i<=7; ++i,t=t*base%mod) ans=(ans+k[i]*t%mod)%mod; return ans;}
	inline ll H2(ll k) {return (-(sum2(k)-5ll)+(sum(k)-3ll)%mod*(n%mod+3ll)%mod-(2ll*n%mod+2ll)*(k%mod-2ll)%mod)%mod*Gm%mod;}
	inline ll qpow(ll a, ll b) {a%=mod; ll ans=1ll; for (; b; a=a*a%mod,b>>=1) if (b&1) ans=ans*a%mod; return ans;}
	struct matrix{
		int n, m;
		ll a[10][10];
		inline void resize(int s, int t) {n=s; m=t; memset(a, 0, sizeof(a));}
		inline void put() {for (int i=1; i<=n; ++i) {for (int j=1; j<=m; ++j) cout<<a[i][j]<<' '; cout<<endl;}}
		inline ll* operator [] (int t) {return a[t];}
		void gauss(ll ans[]) {
			for (int i=1; i<=n; ++i) {
				int r=i;
				for (int j=i+1; j<=n; ++j) if (llabs(a[j][i])>llabs(a[r][i])) r=j;
				swap(a[i], a[r]);
				for (int j=1; j<=n; ++j) {
					if (i==j) continue;
					ll d=a[j][i]*qpow(a[i][i], mod-2)%mod;
					for (int k=i; k<=m; ++k) {
						a[j][k]=(a[j][k]-a[i][k]*d%mod)%mod;
						a[j][k]=(a[j][k]%mod+mod)%mod;
					}
				}
			}
			for (int i=1; i<=n; ++i) ans[i]=a[i][m]*qpow(a[i][i], mod-2)%mod;
		}
	}mat;
	ll solve(ll now) {
		r=now;
		int lim=10;
		fac[0]=fac[1]=1; inv[0]=inv[1]=1; inv2[0]=inv2[1]=1;
		for (int i=2; i<=lim; ++i) fac[i]=fac[i-1]*i%mod;
		for (int i=2; i<=lim; ++i) inv[i]=(mod-mod/i)*inv[mod%i]%mod;
		for (int i=2; i<=lim; ++i) inv2[i]=inv2[i-1]*inv[i]%mod;
		Gm=G(m); mat.resize(7, 8);
		// cout<<"G: "<<Gm<<endl;
		for (int i=3; i<=9; ++i) {
			ll tem=1ll;
			for (int j=1; j<=7; ++j,tem=tem*i%mod) mat[i-2][j]=tem;
			tem=0;
			for (int j=3; j<=i; ++j) tem=((tem+1ll*(j-2)*(n%mod-j+1)%mod*G(r/2-j+2)%mod)%mod+mod)%mod;
			mat[i-2][8]=tem;
		}
		#if 0
		mat.put(); cout<<endl;
		mat.gauss(k);
		mat.put(); cout<<endl;
		for (int i=3; i<=15; ++i) {
			ll tem=0;
			for (int j=3; j<=i; ++j) tem=((tem+1ll*(j-2)*(n-j+1)%mod*G(r/2-j+2)%mod)%mod+mod)%mod;
			cout<<"H1: "<<H1(i)<<' '<<tem<<endl;
		}
		for (int i=3; i<=15; ++i) {
			ll tem=0;
			for (int j=3; j<=i; ++j) tem=(tem+1ll*(j-2)*(m-j+1)%mod)%mod;
			// cout<<"G: "<<G(i)<<' '<<tem<<endl;
		}
		for (int i=3; i<=15; ++i) {
			ll tem=0;
			for (int j=3; j<=i; ++j) tem=(tem+1ll*(j-2)*(n-j+1)%mod*G(m)%mod)%mod;
			cout<<"H2: "<<H2(i)<<' '<<tem<<endl;
		}
		#else
		mat.gauss(k);
		#endif

		// cout<<H1(10000)<<endl;
		ll t=r/2-m+2;
		ll x=min(n, r/2-1);
		ll ans=0;
		// cout<<"xt: "<<x<<' '<<t<<' '<<(H1(min(x, t))%mod+mod)%mod<<endl;
		if (x>=t) {
			if (t>3) ans = (ans+H1(x)-H1(t-1))%mod;
			else ans = (ans+H1(x))%mod;
			if (t>3) ans = (ans+H2(t-1))%mod;
			return ans;
		}
		else {
			if (x>=3) return H2(x)%mod;
			// else return H2(3)%mod;
			else return 0;
		}
		// cout<<t<<' '<<x<<endl;
		// cout<<H1(t)-H1(t-1)<<' '<<H2(t)-H2(t-1)<<endl;
		// cout<<H1(x)<<' '<<H1(t-1)<<' '<<H2(t-1)<<endl;
		// return (H1(x)-H1(t-1)+H2(t-1))%mod;
	}
}

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

	n=read(); m=read(); l=read(); r=read();
	// force::solve();
	// cout<<task::solve(r)<<endl;
	// cout<<task::solve(l-1)<<endl;
	printf("%lld\n", ((task::solve(r)-task::solve(l-1))%mod*6ll%mod+mod)%mod);

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