您的位置:首页 > 其它

BZOJ2223(可持久化线段树)

2016-03-05 23:18 288 查看
思路:

很裸的可持久化。不说了。

/**************************************************************
Problem: 2223
User: DtenSherlock
Language: C++
Result: Accepted
Time:1384 ms
Memory:180708 kb
****************************************************************/

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
using namespace std;
const int imax=100000+229;
const int nmax=300000+229;
int n,m,a[nmax],lishi[nmax],tot;
int root[nmax],id;
struct Node{
int lc,rc,count;
}t[nmax*50];

void add(int now,int pos,int l,int r)
{
if(l+1==r) { t[now].count++; return;}
int Mid=(l+r)>>1;
if(pos<Mid) { t[++id]=t[t[now].lc]; add(t[now].lc=id,pos,l,Mid);}
else { t[++id]=t[t[now].rc]; add(t[now].rc=id,pos,Mid,r); }
t[now].count=t[t[now].lc].count+t[t[now].rc].count;
}

int query(int pre,int now,int val,int l,int r)
{
int Mid=(l+r)>>1;
if(l+1==r) return l;
int lcount=t[t[now].lc].count-t[t[pre].lc].count;
int rcount=t[t[now].rc].count-t[t[pre].rc].count;
if(lcount>val) return query(t[pre].lc,t[now].lc,val,l,Mid);
else if(rcount>val) return query(t[pre].rc,t[now].rc,val,Mid,r);
else return 0;
}

void iread()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
lishi[++tot]=a[i];
}
sort(lishi+1,lishi+tot+1);
tot=unique(lishi+1,lishi+tot+1)-(lishi+1);
}

void iwork()
{
root[0]=++id;
for(int i=1;i<=n;i++)
{
root[i]=++id;
t[root[i]]=t[root[i-1]];
int pos=lower_bound(lishi+1,lishi+tot+1,a[i])-lishi;
add(root[i],pos,1,tot+1);
}
int Q,l,r;
scanf("%d",&Q);
for(int i=1;i<=Q;i++)
{
scanf("%d%d",&l,&r);
int pos=query(root[l-1],root[r],(r-l+1)/2,1,tot+1);
if(!pos) puts("no");
else printf("yes %d\n",lishi[pos]);
}
}

int main()
{
//  freopen("p3.in","r",stdin);
iread();
iwork();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  可持久化线段树