hdu 5919Sequence II 主席数的应用 2016CCPC长春
2016-11-05 21:10
330 查看
传送门:Sequence II
给定一个长度为n的串,q次查询每次查询[L,R]区间中的数字的第一个在整个区间中的位置!强制在线操作;
这个题目就是对主席树的这两个应用的综合考察,我们先把这个序列从后向前的按照位置插入主席树,这样就能避免后面出现重复数字对前面的影响,然后我们求出这个区间中有k个不同的数字,我们只需要求出这个区间中第(k+1)/2大就可以了,在这里只要传查询第L棵树就可以了
题目大意
这个题目读题是个大困难呀,不好读;给定一个长度为n的串,q次查询每次查询[L,R]区间中的数字的第一个在整个区间中的位置!强制在线操作;
解题思路
主席树的套路题目;知道主席树的人一定做过主席树的两种应用的题目就是求给定区间的第K大,还有给定区间[L,R],问这个区间中不同数字的个数!这个题目就是对主席树的这两个应用的综合考察,我们先把这个序列从后向前的按照位置插入主席树,这样就能避免后面出现重复数字对前面的影响,然后我们求出这个区间中有k个不同的数字,我们只需要求出这个区间中第(k+1)/2大就可以了,在这里只要传查询第L棵树就可以了
AC代码
#include <cstdio> #include <iostream> #include <map> #include <cstring> using namespace std; const int MX = 2e5+5; const int N = MX*40; int n,q,tot; int A[MX]; int T ,lson ,rson ,sum ; int build(int l,int r) { int rt = tot++; sum[rt] = 0; int mid = (l+r)>>1; if(l!=r) { lson[rt] = build(l,mid); rson[rt] = build(mid+1,r); } return rt; } int update(int rt,int pos,int val) { int nrt = tot++; int tmp = nrt; int l=1,r=n; sum[nrt] = sum[rt] + val; while(l<r) { int mid = (l+r)>>1; if(pos<=mid) { lson[nrt] = tot++; rson[nrt] = rson[rt]; nrt = lson[nrt]; rt = lson[rt]; r = mid; } else { rson[nrt] = tot++; lson[nrt] = lson[rt]; nrt = rson[nrt]; rt = rson[rt]; l = mid+1; } sum[nrt] = sum[rt]+val; } return tmp; } int query(int rt,int pos) { int cnt = 0; int l = 1,r = n; while(pos < r) { int mid = (l + r) >> 1; if(pos <= mid) { rt = lson[rt]; r = mid; } else { cnt += sum[lson[rt]]; rt = rson[rt]; l = mid + 1; } } return cnt + sum[rt]; } int Query(int rt,int k) { int l = 1,r = n; while(l < r){ int mid = (l + r) >> 1; if(sum[lson[rt]] >= k){ rt = lson[rt]; r = mid; } else{ k -= sum[lson[rt]]; rt = rson[rt]; l = mid +1 ; } } return l; } int main() { int _; // freopen("in.txt","r",stdin); scanf("%d",&_); for(int cas=1;cas<=_;cas++) { tot=0; scanf("%d%d",&n,&q); for(int i=1;i<=n;i++) scanf("%d",&A[i]); T[n+1] = build(1,n); map<int,int>mp; for(int i=n;i>0;i--) { if(mp.find(A[i])==mp.end()) T[i] = update(T[i+1],i,1); else { int tmp = update(T[i+1],mp[A[i]],-1); T[i] = update(tmp,i,1); } mp[A[i]] = i; } int ans = 0; printf("Case #%d:",cas); while(q--) { int l,r; scanf("%d%d",&l,&r); l = (l+ans)%n+1; r = (r+ans)%n+1; int ll = min(l,r),rr = max(l,r); int k = (query(T[ll],rr)+1)>>1; if(!k) k=1; ans = Query(T[ll],k); printf(" %d",ans); } puts(""); } return 0; }
相关文章推荐
- 2016 ccpc长春现场赛I Sequence I(hdu 5918)
- HDOJ 5918 Sequence I 【2016CCPC长春现场赛】KMP暴力
- ACM-CCPC中国大学生程序设计竞赛长春赛区(2016)地区赛——花开花落两相知
- CCPC 2016 长春 几道水题的题解
- CCPC 长春 2016 Triangle Fib数列
- HDOJ 5916 Harmonic Value Description 【2016CCPC长春现场赛】数学+构造
- HDU 5920 Ugly Problem 高精度减法大模拟 ---2016CCPC长春区域现场赛
- hdu5912Fraction(2016ccpc长春1002)
- HDU 5916 Harmonic Value Description (2016-ccpc-长春)
- [2016CCPC]长春现场赛重现
- 2016 ccpc长春现场赛J Sequence II(hdu 5919)
- HDU 5912 Fraction (2016-ccpc-长春)
- CCPC 2016 长春赛区 hdu5912
- HDOJ 5912 Fraction 【2016CCPC长春现场赛】数学
- HDU 5914 Triangle (2016-ccpc-长春)
- 2016_09_30_CCPC长春
- HDOJ 5914 Triangle 【2016CCPC长春现场赛】数学
- HDU 5918 Sequence I (2016-ccpc-长春)
- 2016 ccpc(长春) Sequence I (kmp)
- 【bzoj4571】【SCOI2016】【美味】【主席树+贪心】