75 pts WA 飞求助!!!!
  • 板块P7244 章节划分
  • 楼主chlchl
  • 当前回复1
  • 已保存回复1
  • 发布时间2022/10/5 15:19
  • 上次更新2023/10/27 08:41:36
查看原帖
75 pts WA 飞求助!!!!
363036
chlchl楼主2022/10/5 15:19

rt,对着题解看了好久,不知道哪里错了。

#include<bits/stdc++.h>
using namespace std;

const int N = 1e5 + 10;
int n, k, mx, a[N];
int divi[N * 10], lst[N], f[N], rmq[N][20];
//f[i] 为前 i 个数在最大公约数为 v 时最多能分成几段 
vector<int> d;
stack<int> st;

bool cmp(int x, int y){return x > y;}

void update(int id, int val){
	rmq[id][0] = val;
	for(int i=1;(1<<i)<=id;i++)	rmq[id][i] = max(rmq[id][i - 1], rmq[id - (1 << (i - 1))][i - 1]);
}

int query(int l, int r){
	int m = log2(r - l + 1);
	return max(rmq[r][m], rmq[l + (1 << m) - 1][m]);
}

int main(){
	scanf("%d%d", &n, &k);
	for(int i=1;i<=n;i++){
		scanf("%d", &a[i]);
		mx = max(mx, a[i]);
		while(!st.empty() && a[i] >= a[st.top()])	st.pop();
		if(!st.empty())	lst[i] = st.top();//单调栈优化,求出上一个比 a[i] 大的数 
		st.push(i);//入栈 
	}
	for(int i=1;i*i<=mx;i++){
		if(mx % i == 0){
			d.push_back(i);
			for(int j=1;j<=n;j++)
				if(a[j] % i == 0)
					divi[i]++;
			if(i * i != mx){
				d.push_back(mx / i);
				for(int j=1;j<=n;j++)
					if(a[j] % (mx / i) == 0)
						divi[mx / i]++;
			}
		}
	}//分解最大的数的质因数,因为其必定作为某个区间的最大值出现 
	
	sort(d.begin(), d.end(), cmp);//按因子从大到小排序
	for(int v: d){
		f[0] = 0, f[1] = 1;
		update(1, f[1]);
		for(int i=2;i<=n;i++){
			if(a[i] % v != 0){
				f[i] = f[lst[i]];
				update(i, f[i]);
				continue;
			}
			if(lst[i] == 0){//前缀最大值 
				int t = query(lst[i] + 1, i - 1);//找到前缀中的dp最大值 
				f[i] = (!t ? 0 : t + 1);
			}
			else{ 
				int t = query(lst[i], i - 1);//从上一个比他大的数的位置开始取dp最大值 
				f[i] = (!t ? 0 : t + 1);//如果前面都分不成,显然后面的也不可能分成,记为 0 
			}
			update(i, f[i]);//更新 dp 值到 ST 表中
		}
		if(divi[v] >= k && f[n] >= k)
			return printf("%d\n", v), 0;
	}
	return 0;
}
2022/10/5 15:19
加载中...