ABC 269F - Numbered Checker(数学)

Posted Harris-H

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ABC 269F - Numbered Checker(数学)相关的知识,希望对你有一定的参考价值。

ABC 269F - Numbered Checker(数学)

纯找规律题目,我是根据行数和列数的奇偶性分四种情况讨论。

实际上可以二维前缀和差分然后直接做更简洁。

法1(我的)

// Problem: F - Numbered Checker
// Contest: AtCoder - UNICORN Programming Contest 2022(AtCoder Beginner Contest 269)
// URL: https://atcoder.jp/contests/abc269/tasks/abc269_f
// Memory Limit: 1024 MB
// Time Limit: 3000 ms
// Date: 2022-10-01 13:27:14
// --------by Herio--------

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull; 
const int N=1e3+5,M=2e4+5,inf=0x3f3f3f3f,mod=998244353;
const int hashmod[4] = 402653189,805306457,1610612741,998244353;
#define mst(a,b) memset(a,b,sizeof a)
#define db double
#define PII pair<int,int>
#define PLL pair<ll,ll>
#define x first
#define y second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define all(a) a.begin(),a.end()
#define VI vector<int>
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define per(i,a,b) for(int i=a;i>=b;--i)
#define ios ios::sync_with_stdio(false),cin.tie(nullptr) 
void Print(int *a,int n)
	for(int i=1;i<n;i++)
		printf("%d ",a[i]);
	printf("%d\\n",a[n]); 

template <typename T>		//x=max(x,y)  x=min(x,y)
void cmx(T &x,T y)
	if(x<y) x=y;

template <typename T>
void cmn(T &x,T y)
	if(x>y) x=y;

ll n,m;
ll ksm(ll a,ll n,ll m=mod)
	ll ans=1;
	while(n)
		if(n&1) ans=ans*a%m;
		a=a*a%m;
		n>>=1;
	
	return ans;

ll dfs(ll a,ll b,ll c,ll d)
	if(a>b || c>d) return 0;
	ll rc = b-a+1;
	ll cc = d-c+1;
	if((rc%2==0)&&(cc%2==0))
		rc%=mod;
		cc%=mod;
		ll l = ((a-1)*m%mod+c)%mod;
		ll p1 = (l+l+d-c)*cc%mod*ksm(2,mod-2)%mod;
		p1%=mod;
		//printf("m=%lld cc=%lld %lld\\n",m,cc,m*cc%mod);
		ll dd = (m*cc)%mod;
		//printf("%lld %lld\\n",p1,dd);
		ll sum = (p1+p1+dd*(b-a)%mod)*rc%mod*ksm(2,mod-2)%mod;
		return sum*ksm(2,mod-2)%mod;
	
	else if(cc%2==0)
		rc%=mod;
		cc%=mod;
		ll tmp = dfs(a,b-1,c,d);
		ll l = ((b-1)*m%mod+c)%mod;
		ll sum = (l+l+(d-c))*cc%mod*ksm(2,mod-2)%mod;
		ll cnt = cc*ksm(2,mod-2)%mod;
		sum = (sum-cnt)*ksm(2,mod-2)%mod;
		if((b+c)&1) sum=(sum+cnt)%mod;
		return (sum+tmp)%mod;
	
	else if(rc%2==0)
		rc%=mod;
		cc%=mod;
		ll tmp = dfs(a,b,c,d-1);
		ll l = ((a-1)*m%mod+d)%mod;
		if((a+d)&1) l+=m;
		l%=mod;
		ll cnt = rc*ksm(2,mod-2)%mod;
		ll sum = (l+l+(cnt-1)*(2*m)%mod)*cnt%mod*ksm(2,mod-2)%mod;
		return (sum+tmp)%mod;
	
	else 
		ll tmp = dfs(a,b-1,c,d);
		ll tmp1 = dfs(b,b,c,d-1);
		//printf("%lld %lld---\\n",tmp,tmp1);
		tmp=(tmp+tmp1)%mod;
		ll tmp2 = (b-1)*m+d;
		if((b+d)&1) tmp2=0;
		return (tmp+tmp2)%mod;
	
	return 0;

int main()
	
	cin>>n>>m;
	int q;cin>>q;
	n%=mod,m%=mod;
	while(q--)
		ll a,b,c,d;cin>>a>>b>>c>>d;
		//a%=mod,b%=mod,c%=mod,d%=mod;
		ll tmp = dfs(a,b,c,d);
		printf("%lld\\n",(tmp+mod)%mod);
		
	
	return 0;


法2 二维差分。

#include<cstdio>
#define ll long long
const int mo=998244353,inv2=mo/2+1;
int n,m,q,a,b,c,d;
ll sum(ll a,ll b,ll c)return (a+a+b*(c-1))%mo*c%mo*inv2%mo;
ll query(int a,int b)

	return (sum(1,m+m,a+1>>1)*(b+1>>1)%mo+sum(0,2,b+1>>1)*(a+1>>1)%mo
	+sum(m+2,m+m,a>>1)*(b>>1)%mo+sum(0,2,b>>1)*(a>>1)%mo)%mo;

int main()

	scanf("%d%d%d",&n,&m,&q);
	while(q--)
	
		scanf("%d%d%d%d",&a,&b,&c,&d);
		printf("%lld\\n",(query(b,d)-query(a-1,d)-query(b,c-1)+query(a-1,c-1)+mo+mo)%mo);
	
  

以上是关于ABC 269F - Numbered Checker(数学)的主要内容,如果未能解决你的问题,请参考以下文章

MySQL 中的 CHECK 约束不起作用

ABC291题解(D-G)

1003. Check If Word Is Valid After Substitutions

ABC207 C - Many Segments(暴力,线段判交)

创建单独的字典,其中包含值列表

ABC215 F - Dist Max 2(二分,排序降维,双指针)