FJOI2016 神秘数
题目描述:
题解:
没有多组询问的话非常好做。
先排个序,对小于等于当前总和+1的所有数求和,然后更新当前总和直到更新不了。
这题就是再套个主席树……
代码:
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N = 100050; const int M = 80*N; const int inf = 1000000000; template<typename T> inline void read(T&x) { T f = 1,c = 0;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();} x = f*c; } int n,m,rt[N]; struct pertree { int tot,ls[M],rs[M]; int w[M]; void insert(int l,int r,int&u,int las,int qx) { u=++tot;ls[u]=ls[las],rs[u]=rs[las],w[u]=w[las]+qx; if(l==r)return ; int mid = (l+r)>>1; if(qx<=mid)insert(l,mid,ls[u],ls[las],qx); else insert(mid+1,r,rs[u],rs[las],qx); } int query(int l,int r,int L,int R,int ql,int qr) { if(!L&&!R)return 0; if(l==ql&&r==qr)return w[R]-w[L]; int mid = (l+r)>>1; if(qr<=mid)return query(l,mid,ls[L],ls[R],ql,qr); else if(ql>mid)return query(mid+1,r,rs[L],rs[R],ql,qr); else return query(l,mid,ls[L],ls[R],ql,mid)+query(mid+1,r,rs[L],rs[R],mid+1,qr); } }tr; int main() { read(n); for(int x,i=1;i<=n;i++) read(x),tr.insert(1,inf,rt[i],rt[i-1],x); read(m); for(int l,r,i=1;i<=m;i++) { read(l),read(r); int ans=1,tmp; while((tmp=tr.query(1,inf,rt[l-1],rt[r],1,ans))>=ans) ans=tmp+1; printf("%d\n",ans); } return 0; }