社区讨论

单调队列+二分 WA0pts,求助!

P1419寻找段落参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@lp8eryzo
此快照首次捕获于
2023/11/21 22:05
2 年前
此快照最后确认于
2023/11/22 12:40
2 年前
查看原帖
和大家的思路一样,二分平均值,check 函数利用单调队列 O(n)\def\timeO#1{\text{O(#1)}} \timeO{n} 解决,总复杂度为 O(n log n)\def\timeO#1{\text{O(#1)}} \timeO{n log n}.
代码:
CPP
using namespace std;
const int N = 1e7+5;
int n, m;
int s[N],a[N],S,T;
deque<int> q,emp;
bool check(double x) {
	q = emp;
    q.push_back(0)	;
    for(int i = 1; i <= n; i++) {
        while(q.front() + T < i) { q.pop_front();}
		if(i - q.front() >= S && i - q.front() <= T) {
			if((s[i]-s[q.front()])*1.0/(i-q.front()) >= x) return 1;
		}
        while(!q.empty() && s[q.back()] >= s[i]) { q.pop_back(); }
        q.push_back(i);
    }
    return 0;
}
int main() {
    scanf("%d%d%d", &n, &S, &T);
    for(int i = 1; i <= n; i++) {
        scanf("%d",a + i);
        s[i] = s[i - 1] + a[i];
    }
    double l=-1e5,r=1e5;
    while(l+0.0001<r) {
		double mid=(l+r)/2;
		if(check(mid)) l=mid;
		else r=mid-1;
    }
    printf("%.3lf",l);
    return 0;
}

#include<bits/stdc++.h>
using namespace std;
const int N = 1e7+5;
int n, m;
int s[N],a[N],S,T;
deque<int> q,emp;
bool check(double x) {
	q = emp;
    q.push_back(0)	;
    for(int i = 1; i <= n; i++) {
        while(q.front() + T < i) { q.pop_front();}
		if(i - q.front() >= S && i - q.front() <= T) {
			if((s[i]-s[q.front()])*1.0/(i-q.front()) >= x) return 1;
		}
        while(!q.empty() && s[q.back()] >= s[i]) { q.pop_back(); }
        q.push_back(i);
    }
    return 0;
}
int main() {
    scanf("%d%d%d", &n, &S, &T);
    for(int i = 1; i <= n; i++) {
        scanf("%d",a + i);
        s[i] = s[i - 1] + a[i];
    }
    double l=-1e5,r=1e5;
    while(l+0.0001<r) {
		double mid=(l+r)/2;
		if(check(mid)) l=mid;
		else r=mid-1;
    }
    printf("%.3lf",l);
    return 0;
}

回复

0 条回复,欢迎继续交流。

正在加载回复...