蒟蒻求调
查看原帖
蒟蒻求调
461359
huangrenheluogu楼主2023/12/30 20:12

rt,听大佬说这题都是蓝的,但是我过不了。

#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
int T, n, maxn[N][20], secmaxn[N][20], V, ans[N], lg[N], L, R, Max, Sec, resmax, ressec;
struct node{
	int a, h, id;
}a[N];
inline void init(){
	for(int i = 1; i <= n; i++){
		for(int j = 0; j < 19; j++){
			maxn[i][j] = secmaxn[i][j] = 0;
		}
		ans[i] = 0;
	}
	for(int i = 2; i <= n; i++) lg[i] = lg[i >> 1] + 1;
	V = 0;
}
inline bool cmp(node x, node y){
	return x.a < y.a;
}
inline int Maxx(int x, int y){
	return a[x].h < a[y].h ? y : x;
}
inline void rmq(){
	for(int i = 1; i <= n; i++){
		maxn[i][0] = i;
		secmaxn[i][0] = 0;
	}
	int tmp;
	for(int j = 1; j <= lg[n]; j++){
		for(int i = 1; i + (1 << j) - 1 <= n; i++){
			maxn[i][j] = Maxx(maxn[i][j - 1], maxn[i + (1 << j - 1)][j - 1]);
			tmp = maxn[i][j - 1] == maxn[i][j] ? (i + (1 << j - 1)) : i;
			tmp = maxn[tmp][j - 1];
			secmaxn[i][j] = Maxx(tmp, Maxx(secmaxn[i][j - 1], secmaxn[i + (1 << j - 1)][j - 1]));
		}
	}
}
inline void get(int x, int y){
	int tt = lg[y - x + 1];
	int tmp;
	resmax = Maxx(maxn[x][tt], maxn[y - (1 << tt) + 1][tt]);
	ressec = 0;
	if(resmax != maxn[x][tt]) ressec = Maxx(ressec, maxn[x][tt]);
	if(resmax != maxn[y - (1 << tt) + 1][tt]) ressec = Maxx(ressec, maxn[y - (1 << tt) + 1][tt]);
	ressec = Maxx(ressec, Maxx(secmaxn[x][tt], secmaxn[y - (1 << tt) + 1][tt]));
}
inline int calc(int x, int i){
	return (a[i].a + x - 1) / x * a[i].h;
}
inline void upd(int x, int i){
	if(calc(x, i) > calc(x, Max)){
		Sec = Max;
		Max = i;
		return ;
	}
	if(calc(x, i) > calc(x, Sec)){
		Sec = i;
	}
}
int main(){
	scanf("%d", &T);
	while(T--){
		scanf("%d", &n);
		init();
		for(int i = 1; i <= n; i++) scan+f("%d", &a[i].h);
		for(int i = 1; i <= n; i++){
			scanf("%d", &a[i].a);
			a[i].id = i;
			V = max(V, a[i].a);
		}
		sort(a + 1, a + n + 1, cmp);
		rmq();
		for(int x = 1; x <= V; x++){
			L = 1, R = 0;
			Max = Sec = resmax = ressec = 0;
			for(int j = 1; (j - 1) * x < V; j++){
				while(a[R + 1].a <= j * x && R < n) R++;
				while(a[L].a <= (j - 1) * x && L <= n) L++;
				if(L <= R) get(L, R);
				upd(x, resmax);
				upd(x, ressec);
			}
			ans[a[Max].id] = max(ans[a[Max].id], calc(x, Max) - calc(x, Sec));
		}
		for(int i = 1; i <= n; i++) printf("%d ", ans[i]);
		puts("");
	}
	return 0;
}
/*
1
8
8 8 10 1 4 3 10 2
1 3 1 6 9 7 3 9
*/
2023/12/30 20:12
加载中...