CF1342 Otro problema más de conteo

responder:

No tengo idea, encontré que los valores de x% a% byx% b% a aparecen periódicamente, y el tamaño del período es a * b / gcd (a, b). Sabiendo que el valor máximo de ayb es 200, entonces podemos registrar el número de x% a% b! = X% b% a en este período, y luego usar el prefijo y contar el número de x que cumple la condición cuando es menos de un período. Consulte el código para obtener más detalles.

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

 

Supongo que te gusta

Origin blog.csdn.net/qq_44132777/article/details/105794549
Recomendado
Clasificación