【刷題】BZOJ 3524 [Poi2014]Couriers
阿新 • • 發佈:2018-03-18
last void -- 表示 一個數 amp con 出現 pos
每次查詢的時候選擇滿足條件的往下走就行了
因為一段數列中出現次數大於一半的至多只會有一個,所以這樣暴力做的復雜度是正確的
Description
給一個長度為n的序列a。1≤a[i]≤n。
m組詢問,每次詢問一個區間[l,r],是否存在一個數在[l,r]中出現的次數大於(r-l+1)/2。如果存在,輸出這個數,否則輸出0。
Input
第一行兩個數n,m。
第二行n個數,a[i]。
接下來m行,每行兩個數l,r,表示詢問[l,r]這個區間。
Output
m行,每行對應一個答案。
Sample Input
7 5
1 1 3 2 3 4 3
1 3
1 4
3 7
1 7
6 6
Sample Output
1
0
3
0
4
HINT
【數據範圍】
n,m≤500000
Solution
維護數字出現次數——主席樹
同樣用主席樹維護\(sum\)
每次查詢的時候選擇滿足條件的往下走就行了
因為一段數列中出現次數大於一半的至多只會有一個,所以這樣暴力做的復雜度是正確的
#include<bits/stdc++.h> #define ll long long #define db double #define ld long double #define Mid ((l+r)>>1) #define lson l,Mid #define rson Mid+1,r const int MAXN=500000+10; int n,m,A[MAXN]; std::vector<int> V; std::map<int,int> M; struct ChairMan_Tree{ int cnt,lc[MAXN<<5],rc[MAXN<<5],sum[MAXN<<5],root[MAXN]; inline void init() { cnt=0; memset(lc,0,sizeof(lc)); memset(rc,0,sizeof(rc)); memset(sum,0,sizeof(sum)); } inline void Build(int &rt,int l,int r) { rt=++cnt; sum[rt]=0; if(l==r)return ; Build(lc[rt],lson); Build(rc[rt],rson); } inline void Insert(int &rt,int l,int r,int last,int pos) { rt=++cnt; sum[rt]=sum[last]+1; lc[rt]=lc[last]; rc[rt]=rc[last]; if(l==r)return ; else { if(pos<=Mid)Insert(lc[rt],lson,lc[last],pos); else Insert(rc[rt],rson,rc[last],pos); } } inline int Query(int now,int last,int l,int r,int k) { if(sum[now]-sum[last]<=k)return 0; if(l==r)return l; else { if(sum[lc[now]]-sum[lc[last]]>k)return Query(lc[now],lc[last],lson,k); else return Query(rc[now],rc[last],rson,k); } } }; ChairMan_Tree T; template<typename T> inline void read(T &x) { T data=0,w=1; char ch=0; while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar(); if(ch=='-')w=-1,ch=getchar(); while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar(); x=data*w; } template<typename T> inline void write(T x,char c='\0') { if(x<0)putchar('-'),x=-x; if(x>9)write(x/10); putchar(x%10+'0'); if(c!='\0')putchar(c); } template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);} template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);} template<typename T> inline T min(T x,T y){return x<y?x:y;} template<typename T> inline T max(T x,T y){return x>y?x:y;} inline void discre() { sort(V.begin(),V.end()); V.erase(unique(V.begin(),V.end()),V.end()); for(register int i=1;i<=n;++i) { int pre=A[i]; A[i]=lower_bound(V.begin(),V.end(),A[i])-V.begin()+1; M[A[i]]=pre; } } int main() { read(n);read(m); for(register int i=1;i<=n;++i) { read(A[i]); V.push_back(A[i]); } discre(); T.init(); T.Build(T.root[0],1,n); for(register int i=1;i<=n;++i)T.Insert(T.root[i],1,n,T.root[i-1],A[i]); while(m--) { int l,r; read(l);read(r); write(T.Query(T.root[r],T.root[l-1],1,n,(r-l+1)/2),'\n'); } return 0; }
【刷題】BZOJ 3524 [Poi2014]Couriers