CF1342 Yet Another Counting Problem

题解:

没有思路,打表发现 x%a%b ,x%b%a 的值成周期性出现,周期大小为a*b/gcd(a,b)。又知a,b最大为200,那么我们可以记录这个周期内x%a%b!=x%b%a的个数,再用前缀和统计不足一个周期时满足该条件x的个数。具体见代码

#include <bits/stdc++.h>
using namespace std;
#define Fr(i,a,b) for(int i=a;i<=b;i++)
#define fr(i,a,b) for(int i=a;i<b;i++)
#define me(a,b) memset(a,b,sizeof(a))
#define pu push_back
#define fi first
#define se second
#define mp make_pair 
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
const int inf=0x3f3f3f3f;
const int maxn=2e5+5;
int t;
ll a,b,l,r;
int q;
int a1[5000],cnt;
int main() {
	scanf("%d",&t);
	while(t--){
		scanf("%lld%lld%d",&a,&b,&q);
		if(a>b) swap(a,b);
		if(a==b){
			while(q--){
				scanf("%lld%lld",&l,&r);
				printf("0 ");
			}
			printf("\n");
			continue;
		} 
		ll s=0;cnt=0;
		for(int i=1;;i++){
			if(i%a==0&&i%b==0) {
				cnt=i;break;
			}
			if(i%a%b!=i%b%a) {
				s++; a1[i]=a1[i-1]+1;
			} else a1[i]=a1[i-1];
		}
		while(q--){
			scanf("%lld%lld",&l,&r);
			l--;
			ll s1=l/cnt*s+a1[l%cnt];
			ll s2=r/cnt*s+a1[r%cnt];
			printf("%lld ",s2-s1);
		}
		printf("\n");
	}
	
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_44132777/article/details/105794549