HDU6602 Longest Subarray hdu多校第二场 线段树
发布时间:2020-12-13 22:17:44 所属栏目:PHP教程 来源:网络整理
导读:HDU6602 Longest Subarray 线段树 传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6602 题意: 给你一段区间,让你求最长的区间使得区间出现的数字的个数大于k 题解: 比较巧妙的的线段树更新的做法 我们选择的区间吗,该区间内出现的数字的个数必须要
HDU6602 Longest Subarray 线段树传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6602 题意:给你一段区间,让你求最长的区间使得区间出现的数字的个数大于k 题解:比较巧妙的的线段树更新的做法 我们选择的区间吗,该区间内出现的数字的个数必须要满足条件 我们转换一下,我们以当前点为右端点,往左找一个满足条件的左端点,即可更新答案 我们将每个点给予一个权值C-1,更新这个点的数字上次出现的位置之前到现在这个位置-1的一段减1 如果满足这个点的值出现的次数大于k次的话,我们将上一次满足出现k次出现的一段位置给加上1 最后得到当前位置之前满足条件的左端点更新答案 这里巧妙的使用了条件作为线段树查询的条件,所以线段树查询出来的左端点就是满足条件的最远的左端点 代码:#include <set> #include <map> #include <stack> #include <cmath> #include <queue> #include <cstdio> #include <string> #include <vector> #include <cstring> #include <iostream> #include <algorithm> using namespace std; typedef long long LL; typedef pair<int,int> pii; typedef unsigned long long uLL; #define ls rt<<1 #define rs rt<<1|1 #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 #define bug printf("*********n") #define FIN freopen("input.txt","r",stdin); #define FON freopen("output.txt","w+",stdout); #define IO ios::sync_with_stdio(false),cin.tie(0) #define debug1(x) cout<<"["<<#x<<" "<<(x)<<"]n" #define debug2(x,y) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<"]n" #define debug3(x,y,z) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<" "<<#z<<" "<<z<<"]n" const int maxn = 3e5 + 5; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; const double Pi = acos(-1); /* 如果右端点固定,对于每种元素,可行的左端点下标是两段连续的区间。 对于每种元素,将它的可行左端点区间在线段树中加1。 当右端点右移的时候,维护C 种元素的可行左端点。 查询时只要询问线段树中札小的、值为C 的下标即可。*/ LL quick_pow(LL x,LL y) { LL ans = 1; while(y) { if(y & 1) { ans = ans * x % mod; } x = x * x % mod; y >>= 1; } return ans; } int n,C,k; int Max[maxn << 2]; int lazy[maxn << 2]; int pos[maxn << 2]; void push_up(int rt) { Max[rt] = max(Max[ls],Max[rs]); pos[rt] = (Max[rt] == Max[ls] ? pos[ls] : pos[rs]); } void build(int l,int r,int rt) { Max[rt] = lazy[rt] = 0; pos[rt] = l; if(l == r) return; int mid = (l + r) >> 1; build(lson); build(rson); } void push_down(int rt) { if(lazy[rt]) { lazy[ls] += lazy[rt]; lazy[rs] += lazy[rt]; Max[ls] += lazy[rt]; Max[rs] += lazy[rt]; lazy[rt] = 0; } } void update(int L,int R,int val,int l,int rt) { if(L > R) return; if(L <= l && r <= R) { Max[rt] += val; lazy[rt] += val; return; } push_down(rt); int mid = (l + r) >> 1; if(L <= mid) update(L,R,val,lson); if(R > mid) update(L,rson); push_up(rt); } int query(int L,int rt) { if(Max[rt] != C) return 0; if(L <= l && r <= R) { return pos[rt]; } int mid = (l + r) >> 1; push_down(rt); if(L <= mid) { int t = query(L,lson); if(t) return t; } if(R > mid) return query(L,rson); return 0; } vector<int> vec[maxn]; int main() { #ifndef ONLINE_JUDGE FIN #endif while(scanf("%d%d%d",&n,&C,&k) != EOF) { for(int i = 1; i <= C; i++) { vec[i].clear(); vec[i].push_back(0); } build(1,n,1); int ans = 0; for(int i = 1; i <= n; i++) { int c; scanf("%d",&c); update(i,i,C - 1,1,1); update(vec[c].back() + 1,i - 1,-1,1); vec[c].push_back(i); int p = vec[c].size() - k - 1; if(p >= 0) { update(vec[c][p] + 1,vec[c][p + 1],1); } int j = query(1,1); if(!j) continue; ans = max(ans,i - j + 1); } printf("%dn",ans); } return 0; } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |