X姐推荐做的一道喂狗题= =,的确是挺有想法的一道题。
其实就是treap模板题,注意两个地方,一是数据有重复(WA无数次出的结论),二是必须离线处理查询。
(据说用树状数组和线段树也能A)
第一次理解到原来离线处理作用这么大,具体来说就是对所有查询根据起点和终点排序,由于题目保证了所有查询不相互包含,所以从左向右,每次删除多余的,添加进新来的,然后执行查询操作,保存答案。
Treap真厉害啊,贴个WLJ的模板= =
#include <cstdio> #include <cstring> #include <cstdlib> #include <ctime> #include <climits> #include <cmath> #include <iostream> #include <string> #include <vector> #include <set> #include <map> #include <list> #include <queue> #include <stack> #include <deque> #include <algorithm> using namespace std; const int INF=~0U>>1; class treap { struct node { node* c[2]; int value,key,size; node(int v,node* n):value(v) {c[0]=c[1]=n;size=1;key=rand()-1;} void rz(){size=c[0]->size+c[1]->size+1;} }*root,*null; void rot(node* &t,bool d) { node*c=t->c[d]; t->c[d]=c->c[!d]; c->c[!d]=t; t->rz();c->rz(); t=c; } void insert(node* &t,int x) { if(t==null) {t=new node(x,null);return;} // if(x==t->value) return; bool d=x>t->value; insert(t->c[d],x); if(t->c[d]->key<t->key) rot(t,d); else t->rz(); } void Delete(node* &t,int x) { if(t==null) return; if(t->value==x) { bool d=t->c[1]->key<t->c[0]->key; if(t->c[d]==null) { delete t; t=null; return; } rot(t,d); Delete(t->c[!d],x); } else { bool d=x>t->value; Delete(t->c[d],x); } t->rz(); } int select(node* t,int k) { int r=t->c[0]->size; if(k==r) return t->value; if(k<r) return select(t->c[0],k); return select(t->c[1],k-r-1); } int rank(node*t,int x) { if(t==null) return 0; int r=t->c[0]->size; if(x==t->value) return r; if(x<t->value) return rank(t->c[0],x); return r+1+rank(t->c[1],x); } public: treap() { null=new node(0,0);null->size=0;null->key=INF; root=null; } void ins(int x) { insert(root,x); } int sel(int k) { if(k>root->size) return -INF; return select(root,k-1); } int ran(int x) { return rank(root,x); } void del(int x) { Delete(root,x); } }T; const int maxn = 100010; const int maxm = 50010; int n,m,st,ed; int p[maxn]; struct Feed { int id; int a,b,c; bool operator<(const Feed &o) const { return (a==o.a&&b<o.b) || a<o.a; } }feed[maxm]; int ans[maxm]; int main() { int i; scanf("%d%d",&n,&m); for (i=1;i<=n;i++) scanf("%d",&p[i]); for (i=1;i<=m;i++) scanf("%d%d%d",&feed[i].a,&feed[i].b,&feed[i].c), feed[i].id=i; sort(feed+1,feed+m+1); st=ed=i=0; while (++i<=m) { if (feed[i].a>ed) { T=treap(); st=feed[i].a; ed=feed[i].b; for (int j=st;j<=ed;j++) T.ins(p[j]); } else { for (int j=st;j<feed[i].a;j++) T.del(p[j]); for (int j=ed+1;j<=feed[i].b;j++) T.ins(p[j]); st=feed[i].a; ed=feed[i].b; } ans[feed[i].id]=T.sel(feed[i].c); } for (i=1;i<=m;i++) printf("%d\n",ans[i]); return 0; }