51nod1495 中国好区间

来源:互联网 发布:杀死汝爱真实事件 知乎 编辑:程序博客网 时间:2024/06/03 00:30

题面在这里

这题标签叫做“尺取法”。。一开始感觉很高级。。后来发现就是维护两个指针QAQ

首先将题意转化一下,要求一个区间内的第k大的数>=T,相当于是这个区间内有>=k个数>=T,就是说我们把每个数如果>=T就打标记1,否则是0,然后满足条件的区间即需要区间内1的个数>=k。

那么我们用一下前缀和s[i]表示前i个数内1的个数,然后如果一个区间[x, y]满足要求即需要s[y] - s[x-1] >= k,然后这个前缀和因为是单调的,所以如果[x, y]满足条件,[s, y](s <= x)都满足条件。

所以就用两个指针l, r扫描一遍计算答案就好。


/*************************************************************Problem: 51nod 1495 中国好区间 User: bestFyLanguage: C++Result: AcceptedTime: 531 msMemory: 40976 KBSubmit_Time: 2017/11/15 22:41:41*************************************************************/#include<cstdio>#include<cstring>using namespace std;typedef long long LL;const int N = 10000005;int n, K, T, MOD;LL a, b, c, ans = 0;int s[N];int main(){scanf("%d%d%d%lld%lld%lld%d", &n, &K, &T, &a, &b, &c, &MOD);for (int i = 1; i <= n; i ++){a = (a*b + c)%MOD;s[i] = s[i-1];if (a >= T) s[i] ++;}int l = 0, r = K;while (s[r]-s[l] < K) r ++;while (r <= n){while (l <= r && s[r]-s[l] >= K) l ++;ans += l; r ++;}printf("%lld\n", ans);return 0;}