T1 a T2 b T3 c

期望得分:100+55+0=155
实际得分:90+55+0=145

T1

入阵曲的削弱版,预处理前缀和,双指针确定行的上界和下界,然后维护个桶计算合法数量

挂了十分因为没处理好\(l=0\)

T2

注意到\(a_i\)的大小只有\(1e5\),考虑分别计算\(gcd\in(1,max_a)\)的个数

数组\(c[i]\)表示\(gcd\)\(i\)或其倍数的方案数,数组\(c\)可以每行建个桶然后累乘求出

考虑如何将数组修改为\(gcd\)\(i\)的方案数

多余的情况就是\(gcd\)\(i\)的倍数,那么我们可以倒序求出每个\(c[i]\),然后计算\(c[i]\)时减去\(\sum_{j=2}^{\frac{max_a}{i}}c[i*j]\)

据说这种枚举复杂度是\(O(\ln x)\)的,咱也不会证

部分分就是子任务1爆搜,子任务2数据随机,就可以在搜到\(gcd=1\)时就不搜了,子任务6直接枚举\(C_n^i\)表示选i行,再乘上\(m^i*a\),貌似$ai< 1,2 $ 也挺好搞,但是我没去看

代码

T1

#include<bits/stdc++.h>
using namespace std;
const int N=5e4+11;
int xl[35][N];
int qzhr[35][N];
int sum[N],num;
long long n,m,l,r;
long long ton[35*N];
long long qzh[35*N];
inline int read()
{
	int s=0;
	char ch=getchar();
	while(ch>'9'||ch<'0')
		ch=getchar();
	while(ch>='0'&&ch<='9')
	{
		s=(s<<1)+(s<<3)+(ch^48);
		ch=getchar();
	}
	return s;
}
inline int readm()
{
	int s=0;
	char ch=getchar();
	while(ch>'9'||ch<'0')
		ch=getchar();
	return ch-48;
}
signed main()
{
	long long ans=0;
	bool jd=1;
	n=read();
	m=read();
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
		{
			xl[i][j]=readm();
			if(!xl[i][j])
				jd=0;
		}
	l=read();
	r=read();
	if(jd)
	{
		for(long long i=1;i<=n;i++)
			for(long long j=1;j<=m;j++)
				if(i*j>=l&&i*j<=r)
					ans+=(m-j+1)*(n-i+1);
		cout<<ans<<endl;
		return 0;
	}
	if(l==0&&r==n*m)
	{
		for(long long i=1;i<=n;i++)
			for(long long j=1;j<=m;j++)
				ans+=(m-j+1)*(n-i+1);
		cout<<ans<<endl;
		return 0;
	}
	for(int j=1;j<=m;j++)
		for(int i=1;i<=n;i++)
			qzhr[i][j]=qzhr[i-1][j]+xl[i][j];
	for(int i=1;i<=n;i++)
		for(int j=i;j<=n;j++)
		{
			int qz=0;
			for(int k=1;k<=num;k++)
			{
				ton[sum[k]]=0;
				sum[k]=0;
			}
			num=0;
			for(int k=1;k<=m;k++)
			{
				qz+=qzhr[j][k]-qzhr[i-1][k];
				if(!ton[qz])
	 				sum[++num]=qz;
				ton[qz]++;
	 		}
	 		qzh[0]=ton[0];
	 		for(int k=1;k<=qz;k++)
	 			qzh[k]=qzh[k-1]+ton[k];
	 		for(int k=1;k<=num;k++)
	 			if(sum[k]>=l)
	 			{
	 				ans+=ton[sum[k]]*(qzh[sum[k]-l]-(sum[k]-r-1>=0?qzh[sum[k]-r-1]:0));
	 				if(sum[k]>=l&&sum[k]<=r)
	 					ans+=ton[sum[k]];
				}
	 	}
	 	cout<<ans<<endl;
	 	return 0;
}

T2

#include<bits/stdc++.h>
using namespace std;
const long long mod=1e9+7;
const int N=100011;
int maxx;
int n,m,a[24][N];
long long ton[24][N];
long long tone[24][N];
long long c[N];
long long ans;
inline int read()
{
	int s=0;
	char ch=getchar();
	while(ch>'9'||ch<'0')
		ch=getchar();
	while(ch>='0'&&ch<='9')
	{
		s=(s<<1)+(s<<3)+(ch^48);
		ch=getchar();
	}
	return s;
}
signed main()
{
	n=read();
	m=read();
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
		{
			a[i][j]=read();
			maxx=max(maxx,a[i][j]);
			tone[i][a[i][j]]++;
		}
	for(int i=1;i<=n;i++)
		for(int j=1;j<=maxx;j++)
			for(int k=1;k*j<=maxx;k++)
				ton[i][j]+=tone[i][k*j];
	for(int j=1;j<=maxx;j++)
	{
		c[j]=1;
		for(int i=1;i<=n;i++)
			c[j]=(c[j]*(ton[i][j]+1)%mod);
		c[j]=(c[j]+mod-1)%mod;
	}
	for(int i=maxx;i>=1;i--)
		for(int j=2;j*i<=maxx;j++)
			c[i]=(c[i]-c[i*j]+mod)%mod;
	for(int i=1;i<=maxx;i++)
		ans=(ans+c[i]*(long long)i%mod)%mod;
	cout<<ans<<endl;
	return 0;
}