Codeforces 813E Army Creation 主席树(在线,求[l,r]内比x大的数的个数)
2017-06-12 15:32
309 查看
点击打开链接
题意:n个数a[i],q次询问,n,a[i],q<=1e5.
每次问[l,r]内最多可以选多少个数,满足同一个数的出现次数不超过k?
如果相同的往后数k个 在r内 这个数一定能选
也就是说前面b[i]如果不为n+1就是代表后面第一个达到k个这个数的位置,如果b[i]>r 这个数是肯定可取的,b[i]<r就不取。
一个区间上最多取k个这个数,就取后面k个,前面的不取。query查询查取了多少个就好了。 ans+=query(巴拉巴拉)
设b[i] 从i开始数k个和a[i]相同的数的位置,不存在设为n+1;
则[l,r] 只要b[i]>r的数都能可以被选上,转化为求区间[l,r]内有多少个数>=r
题目要求在线 所以套用主席树
建立权值线段树,前缀i内,第[l,r]大的数有多少个,ans=前缀r内[r,inf]个数-前缀i-1内[r,inf]个数
题意:n个数a[i],q次询问,n,a[i],q<=1e5.
每次问[l,r]内最多可以选多少个数,满足同一个数的出现次数不超过k?
如果相同的往后数k个 在r内 这个数一定能选
也就是说前面b[i]如果不为n+1就是代表后面第一个达到k个这个数的位置,如果b[i]>r 这个数是肯定可取的,b[i]<r就不取。
一个区间上最多取k个这个数,就取后面k个,前面的不取。query查询查取了多少个就好了。 ans+=query(巴拉巴拉)
设b[i] 从i开始数k个和a[i]相同的数的位置,不存在设为n+1;
则[l,r] 只要b[i]>r的数都能可以被选上,转化为求区间[l,r]内有多少个数>=r
题目要求在线 所以套用主席树
建立权值线段树,前缀i内,第[l,r]大的数有多少个,ans=前缀r内[r,inf]个数-前缀i-1内[r,inf]个数
#include <vector> #include <iostream> #include <string> #include <map> #include <stack> #include <cstring> #include <queue> #include <list> #include <stdio.h> #include <set> #include <algorithm> #include <cstdlib> #include <cmath> #include <iomanip> #include <cctype> #include <sstream> #include <functional> //#include <ext/pb_ds/tree_policy.hpp> //#include <ext/pb_ds/assoc_container.hpp> //using namespace __gnu_pbds; using namespace std; #define N 100007 #define FOR(x,n,i) for(int i=x;i<=n;i++) #define FOr(x,n,i) for(int i=x;i<n;i++) int n,m,cnt,root ,a ,b ,x,y,k; struct node { int l,r,sum; }T[N*40]; vector<int> pos ; int build(int l,int r) { int rt=++cnt; T[rt].sum=0,T[rt].l=T[rt].r=0; if(l==r) return rt; int m=(l+r)>>1; T[rt].l=build(l,m); T[rt].r=build(m+1,r); return rt; } void update(int l,int r,int &x,int y,int pos) { T[++cnt]=T[y],T[cnt].sum++;x=cnt; if(l==r) return; int m=(l+r)/2; if(pos<=m) update(l,m,T[x].l,T[y].l,pos); else update(m+1,r,T[x].r,T[y].r,pos); } int query(int l,int r,int c,int L,int R=2e5) { if(l>=L&&r<=R) return T[c].sum; int m=(l+r)>>1; int ans=0; if(L<=m) ans+=query(l,m,T[c].l,L,R); if(R>m) ans+=query(m+1,r,T[c].r,L,R); return ans; } void calc() { for(int i=n;i>=1;i--) { int sz=pos[a[i]].size(); if(sz<k) b[i]=n+1; else b[i]=pos[a[i]][sz-k]; pos[a[i]].push_back(i); } } int main() { cin>>n>>k; //root[0]=build(1,n+1); FOR(1,n,i) scanf("%d",&a[i]); calc(); FOR(1,n,i) update(1,n+1,root[i],root[i-1],b[i]); int l,r,last=0; cin>>m; FOR(1,m,i) { scanf("%d%d",&l,&r); l=((l+last)%n)+1; r=((r+last)%n)+1; if(l>r) swap(l,r); int ans=query(1,n+1,root[r],r+1,2e5)-query(1,n+1,root[l-1],r+1,2e5); printf("%d\n",ans); last=ans; } }
相关文章推荐
- Codeforces 813E Army Creation 主席树(在线,求[l,r]内比x大的数的个数)
- Codeforces 707D Persistent Bookcase(离线dfs或在线主席树)
- Codeforces 813E Army Creation 主席树(在线,求[l,r]内比x大的数的个数)
- Codeforces 813E Army Creation 主席树(在线,求[l,r]内比x大的数的个数)
- Codeforces 813E Army Creation 主席树(在线,求[l,r]内比x大的数的个数)
- Codeforces 813E Army Creation 主席树(在线,求[l,r]内比x大的数的个数)
- Codeforces 813E Army Creation 主席树(在线,求[l,r]内比x大的数的个数)
- Codeforces 813E Army Creation 主席树(在线,求[l,r]内比x大的数的个数)
- Codeforces 813E Army Creation 主席树(在线,求[l,r]内比x大的数的个数)
- Codeforces 813E Army Creation 主席树(在线,求[l,r]内比x大的数的个数)
- Codeforces 813E Army Creation 主席树(在线,求[l,r]内比x大的数的个数)
- Codeforces 813E Army Creation 主席树(在线,求[l,r]内比x大的数的个数)
- Codeforces 813E Army Creation 主席树(在线,求[l,r]内比x大的数的个数)
- Codeforces 813E Army Creation 主席树(在线,求[l,r]内比x大的数的个数)
- SPOJ 3267 DQUERY(主席树在线|树状数组离线)
- Codeforces 787E Till I Collapse 主席树+二分
- CodeForces - 597C:Subsequences (主席树+DP)
- codeforces 840D 主席树
- CodeForces 609 E.Minimum spanning tree for each edge(最小生成树-Kruskal+在线倍增LCA)
- FJUT 3097(hdu 3333) 区间种类数 主席树+在线