[Ybt high-efficiency advanced 4-3-2] [luogu P1890] static interval / gcd interval

Static interval / gcd interval

Topic link: ybt high-efficiency advanced 4-3-2 / luogu P1890

General idea

Give you a sequence, and then ask you the gcd of an interval number each time.

Ideas

Obviously, if you repeat the points in an interval and calculate the gcd value with your current answer, the gcd value will not change as a result.

Naturally, I thought of using ST tables.

Then it's fine.

Code

#include<cstdio>

using namespace std;

int n, m, a[50001], f[50001][16];
int x, y, log[50001];

void get_log() {
    
    //预处理 log
	int now = 1, x = 0;
	while ((now << 1) <= 50000) {
    
    
		for (int i = now; i < (now << 1); i++)
			log[i] = x;
		x++;
		now <<= 1;
	}
	while (now <= 50000) log[now++] = x;
}

int gcd(int x, int y) {
    
    //求 gcd
	if (!y) return x;
	return gcd(y, x % y);
}

int main() {
    
    
	get_log();
	
	scanf("%d %d", &n, &m);
	
	for (int i = 1; i <= n; i++) {
    
    
		scanf("%d", &a[i]);
		f[i][0] = a[i];
	}
	
	for (int i = 1; i <= log[n]; i++)//ST表预处理
		for (int j = 1; j <= n; j++)
			if (j + (1 << (i - 1)) > n) f[j][i] = f[j][i - 1];
				else f[j][i] = gcd(f[j][i - 1], f[j + (1 << (i - 1))][i - 1]);
	
	for (int i = 1; i <= m; i++) {
    
    
		scanf("%d %d", &x, &y);
		int size = log[y - x + 1];//ST表查询
		printf("%d\n", gcd(f[x][size], f[y - (1 << size) + 1][size]));
	}
	
	return 0;
}

Guess you like

Origin blog.csdn.net/weixin_43346722/article/details/115017081