Bzoj3524 [POI2014] Couriers
Description
Give a sequence a with the length of n. 1 ≤ a [I] ≤ n.
The m group asks if a [l, r] interval exists and whether a number appears in [l, r] More than (r-l + 1)/2. If yes, this number is output; otherwise, 0 is output.
Input
The first row has two numbers n and m.
Number of n in the second row, a [I].
In the next m row, there are two numbers in each row, l and r, indicating to ask about the range [l, r.
Output
M rows. Each row corresponds to one answer.
Sample Input7 5
1 1 3 2 3 4 3
1 3
1 4
3 7
1 7
6 6
Sample Output1
0
3
0
4
HINT
[Data Scope]
N, m ≤ 500000
Source
By Dzy
The first line is a persistent line segment tree question.
I will not repeat the knowledge of the persistent line segment tree here. (Because I know, I certainly cannot make it clear ...... = _ =)
The practice of this question is to establish a persistent line segment tree for the weight value, and record the number of occurrences of the number in each interval sum. For the query of the range [l, r], we only need to use the r Line Segment tree to subtract L-1 line segment tree (the weight line segment tree can be added or subtracted ), in this line segment tree, perform recursion layer by layer to determine whether the condition sum> (r-l + 1)/2 is met. If all conditions are met by recursion to the last layer, the answer is found; otherwise, 0 is output.
Because it was the first time to write a persistent line segment tree, write your own understanding: This question uses the prefix and idea to convert the interval operation into two prefixes and subtract, the constructor of the persistent line segment tree is similar to the prefix and so it is much easier to perform this operation.
#include
#include
#include
#include
#include
#include#define F(i,j,n) for(int i=j;i<=n;i++)#define D(i,j,n) for(int i=j;i>=n;i--)#define ll long long#define maxn 500005#define maxm 10000005using namespace std;int n,m,tot;int rt[maxn],ls[maxm],rs[maxm],sum[maxm];inline int read(){int x=0,f=1;char ch=getchar();while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}inline void update(int l,int r,int x,int &y,int v){y=++tot;sum[y]=sum[x]+1;if (l==r) return;ls[y]=ls[x];rs[y]=rs[x];int mid=(l+r)>>1;if (v<=mid) update(l,mid,ls[x],ls[y],v);else update(mid+1,r,rs[x],rs[y],v);}inline int query(int u,int v){int l=1,r=n,mid,x=rt[u-1],y=rt[v],tmp=(v-u+1)>>1;while (l!=r){if (sum[y]-sum[x]<=tmp) return 0;mid=(l+r)>>1;if (sum[ls[y]]-sum[ls[x]]>tmp){r=mid;x=ls[x];y=ls[y];}else if (sum[rs[y]]-sum[rs[x]]>tmp){l=mid+1;x=rs[x];y=rs[y];}else return 0;}return l;}int main(){n=read();m=read();F(i,1,n){int x=read();update(1,n,rt[i-1],rt[i],x);}F(i,1,m){int l=read(),r=read();printf("%d\n",query(l,r));}return 0;}