CF1342 Yet Another Counting Problem

answer:

There is no idea, I found that the values ​​of x%a%b and x%b%a appear periodically, and the period size is a*b/gcd(a,b). Knowing that the maximum value of a and b is 200, then we can record the number of x%a%b!=x%b%a in this period, and then use the prefix and count the number of x that meets the condition when it is less than one period. See the code for details

#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;
}

 

Guess you like

Origin blog.csdn.net/qq_44132777/article/details/105794549