CodeForces - 840D:(主席树求出现区间出现次数大于某值的最小数)
Once, Leha found in the left pocket an array consisting of n integers, and in the right pocket q queries of the form l r k. If there are queries, then they must be answered. Answer for the query is minimal x such that x occurs in the interval l r strictly more than times or - 1 if there is no such number. Help Leha with such a difficult task.
Input
First line of input data contains two integers n and q (1 ≤ n, q ≤ 3·105) — number of elements in the array and number of queries respectively.
Next line contains n integers a1, a2, ..., an (1 ≤ ai ≤ n) — Leha's array.
Each of next q lines contains three integers l, r and k (1 ≤ l ≤ r ≤ n, 2 ≤ k ≤ 5) — description of the queries.
Output
Output answer for each query in new line.
Examples
4 2
1 1 2 2
1 3 2
1 4 2
1
-1
5 3
1 2 1 3 2
2 5 3
1 2 3
5 5 2
2
1
2
题意:给定N个数,Q个询问,每个询问给出L,R,K,求这个区间出现次数大于num=(R-L+1)/K的最小数,没有则输出-1。
思路:参照上一篇博客的“主席树求区间众数”,这一题也差不多。 同样用主席树记录前缀出现次数,线段树上跑的时候,如果这个区间的出现次数小于num,那么忽略这个区间。如果大于大于num,那么再去子区间找是否寻在答案。
(最近状态不错额,做的几个题都有手感。ORZ
#include<bits/stdc++.h> using namespace std; const int maxn=300010; struct node{ int val,l,r; node() {} node(int L,int R,int V):l(L),r(R),val(V){} }s[maxn*20]; int rt[maxn],cnt,ans; void insert(int &now,int pre,int L,int R,int pos,int val) { s[now=++cnt]=node(s[pre].l,s[pre].r,s[pre].val+val); if(L==R) return ; int Mid=(L+R)>>1; if(pos<=Mid) insert(s[now].l,s[pre].l,L,Mid,pos,val); else insert(s[now].r,s[pre].r,Mid+1,R,pos,val); } int query(int now,int pre,int L,int R,int times) { if(L==R) return L; int Mid=(L+R)>>1; int res=maxn,tmp; if(s[s[now].l].val-s[s[pre].l].val>times){ tmp=query(s[now].l,s[pre].l,L,Mid,times); if(tmp!=-1) res=min(res,tmp); } if(s[s[now].r].val-s[s[pre].r].val>times){ tmp=query(s[now].r,s[pre].r,Mid+1,R,times); if(tmp!=-1) res=min(res,tmp); } if(res==maxn) res=-1; return res; } int main() { int N,K,Q,x,y,i,j; scanf("%d%d",&N,&Q); for(i=1;i<=N;i++){ scanf("%d",&x); insert(rt[i],rt[i-1],1,N,x,1); } for(i=1;i<=Q;i++){ scanf("%d%d%d",&x,&y,&K); printf("%d\n",query(rt[y],rt[x-1],1,N,(y-x+1)/K)); } return 0; }