AssignmentTime Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 1565 Accepted Submission(s): 754 Problem Description Tom owns a company and he is the boss. There are n staffs which are numbered from 1 to n in this company, and every staff has a ability. Now, Tom is going to assign a special task to some staffs who were in the same group. In a group, the difference of the Input In the first line a number T indicates the number of test cases. Then for each case the first line contain 2 numbers n, k (1<=n<=100000, 0<k<=10^9),indicate the company has n persons, k means the maximum difference between abilities of staff in a group is less Output For each test,output the number of groups. Sample Input 2 4 2 3 1 2 4 10 5 0 3 4 5 2 1 6 7 8 9 Sample Output 5 28 Hint First Sample, the satisfied groups include:[1,1]、[2,2]、[3,3]、[4,4] 、[2,3] Author FZUACM Source 2015 Multi-University Training Contest 1 Recommend We have carefully selected several similar problems for you: 5309 5308 5307 5306 5305 |
题解: 以数组d[i]表示区间以a[i]结尾满足任意两元素差值小于k的最大长度,
则使用线段树查询在a[i]之前与其差值大于等于k的位置为p
d[i] = max(d[i-1], p+1);
答案即为 sum = 西格玛(d[i] - i + 1);
题目很简单,关键是思路要精确 , 很多时候如果数学思维卡住了,可以使用编程思维来进行解决. 还是很喜欢使用线段树进行解题,多加努力。
#include <cstdio> #include <algorithm> #include <cstring> #include <iostream> using namespace std; #define maxn 100000 + 10 #define lson L, mid, rt<<1 #define rson mid+1, R, rt<<1|1 int n, k; int a[maxn]; int ans; struct Node { int mi, ma; }T[maxn<<2]; void pushup(int rt) { int l = rt<<1, r = rt<<1|1; T[rt].ma = max(T[l].ma, T[r].ma); T[rt].mi = min(T[l].mi, T[r].mi); } void build(int L, int R, int rt) { if(L == R) { T[rt].ma = T[rt].mi = a[L]; return ; } int mid = (L + R) >> 1; build(lson); build(rson); pushup(rt); } ///注意树的节点与区间节点不要混淆 void query(int l, int r, int v, int L, int R, int rt) { if(L == R) { if(abs(T[rt].mi - v) >= k) { if(ans == -1 || ans < L) ans = L; } return ; } int mid = (L + R) >> 1; if(r > mid) if(abs(T[rt<<1|1].mi - v) >= k || abs(T[rt<<1|1].ma - v) >= k) query(l, r, v, rson); if(ans == -1 && l <= mid) if(abs(T[rt<<1].mi - v) >= k || abs(T[rt<<1].ma - v) >= k) query(l, r, v, lson); } int d[maxn]; long long sum; int main() { int t; scanf("%d", &t); while(t--) { sum = 1; scanf("%d%d", &n, &k); for(int i=1; i<=n; i++) scanf("%d", &a[i]); build(1, n, 1); d[1] = 1; for(int i=2; i<=n; i++) { ans = -1; query(1, i, a[i], 1, n, 1); if(ans == -1) d[i] = d[i-1]; else d[i] = max(d[i-1], ans + 1); sum += i - d[i] + 1; } printf("%I64d\n", sum); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。