HDU 5289 Assignment (线段树)
来源:互联网 发布:阿里云企业邮箱下载 编辑:程序博客网 时间:2024/06/03 19:25
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 ability of any two staff is less than k, and their numbers are continuous. Tom want to know the number of groups like this.
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
Output
For each test,output the number of groups.
题意
按序给出 n 个职工的能力值 group
?其中 group
被定义为在同一个 group
中的任意两个职工的能力差不能大于等于 k ,且同一 group
中的职工编号连续。每个职工可以属于多个 group
。
解题思路
为避免重复统计,以编号 i 的职工对结果的贡献仅统计以其为 group
左区间,右区间为 R 的贡献。
对于编号 i 的职工,查找满足
则对于职工 i 的真正右边界,即为区间
代码
#include<bits/stdc++.h>using namespace std;const int N = 100000 + 10;int T, n, k, a[N], r[N];pair<int, int> p, q;set<pair<int, int> > st;set<pair<int, int> >::iterator it, ip;vector<set<pair<int, int> >::iterator > v;bool operator<(pair<int, int> a, pair<int, int> b) { if(a.first == b.first) return a.second < b.second; return a.first < b.first;}void ERASE() { for(int i=0;i<v.size();i++) st.erase(v[i]); v.clear();}const int TREE_SIZE = (N << 2) + 10;class IntervalTree{ private: int Cover[TREE_SIZE],Top[TREE_SIZE]; int size; int _Query(int a,int b,int l,int r,int idx) { if(a <= l && b >= r) return Top[idx]; int mid = (l+r)>>1, ret = Cover[idx]; if(a<=mid) ret = min(ret,_Query(a,b,l,mid,idx<<1)); if(b>mid) ret = min(ret,_Query(a,b,mid+1,r,(idx<<1)+1)); return ret; } void _Modify(int a,int l,int r,int idx,int d) { if(l==r && l==a) { Cover[idx]=Top[idx]=d; return; } int mid = (l+r)>>1; if(a<=mid) _Modify(a,l,mid,idx<<1,d); else _Modify(a,mid+1,r,(idx<<1)+1,d); Top[idx]=min(Top[idx<<1],Top[(idx<<1)+1]); } public: IntervalTree(){ memset(Cover,0x3f,sizeof(Cover)); memset(Top,0x3f,sizeof(Top)); size = (TREE_SIZE>>2) - 1; } IntervalTree(int size):size(size){ memset(Cover,0x3f,sizeof(Cover)); memset(Top,0x3f,sizeof(Top)); } void init() { memset(Cover, 0x3f, sizeof(Cover)); memset(Top, 0x3f, sizeof(Top)); size = (TREE_SIZE>>2) - 1; } int Query(int a,int b){ return _Query(a,b,1,size,1); } void Modify(int a,int d){ return _Modify(a,1,size,1,d); }} rmq;int main(){ scanf("%d",&T); while(T-- && scanf("%d %d",&n,&k)!=EOF) { rmq.init(); for(int i=1;i<=n;i++) scanf("%d",&a[i]), r[i] = n; st.clear(); for(int i=1;i<=n;i++) { p = make_pair(a[i]-k, n+1); it = st.upper_bound(p); while(1) { if(it == st.begin()) break; it--; r[it->second] = i-1; v.push_back(it); } ERASE(); p = make_pair(a[i]+k, 0); it = st.lower_bound(p); for(;it!=st.end();it++) { r[it->second] = i-1; v.push_back(it); } ERASE(); st.insert(make_pair(a[i], i)); } for(int i=1;i<=n;i++) rmq.Modify(i, r[i]); long long ans = 0; for(int i=1;i<=n;i++) ans += rmq.Query(i, r[i])-i+1; printf("%I64d\n", ans); }}
- HDU 5289 Assignment (线段树)
- 【线段树】 HDU 5289 Assignment
- HDU 5289 Assignment(线段树)
- hdu 5289 Assignment(数学)
- HDU 5289 Assignment (RMQ+二分)
- HDU 5289 Assignment(尺取法)
- HDU 5289 Assignment (二分+RMQ)
- HDU 5289 Assignment(RMQ+二分)
- hdu 5289 Assignment
- HDU 5289 Assignment
- hdu 5289 Assignment
- HDU 5289 Assignment
- hdu 5289 Assignment
- HDU 5289 Assignment
- hdu 5289 Assignment(RMQ)
- hdu 5289 Assignment
- HDU 5289 Assignment
- HDU 5289 Assignment
- JS正则表达式验证账号、手机号、电话和邮箱
- 采用Rhino在JAVA中运行JavaScript
- js 去掉字符串最后一个逗号 “,”
- tcp三次握手及其必要性
- 模板引擎
- HDU 5289 Assignment (线段树)
- MySQL数据库 范式
- 算法竞赛——入门经典p35
- JSON的语法
- JAVA:JDBC连接MySQL数据库
- 自动文档摘要评价方法:Edmundson,ROUGE
- [OpenCV] RGB to YCBCR
- 插入排序
- java.lang.ClassCastException:android.widget.LinearLayout$LayoutParams cannot be cast to android.widg