bzoj 4408

Ok..

First consider if only once ask how we do

We currently have a set number of sets {$ S $}, carried out the inquiry, how do we deal with?

First Let's assume that {$ S $} is not monotonic drop (if not, then obviously the sort and does not affect the answer)

Then the first number is assumed $ I $ is legal, the maximum value can be combined in the $ $ Lim, we only need to compare $ S_ {i + 1} $ size $ lim + 1 $ can determine whether the answer is increases

why?

$ I $ before the number can be expressed $ lim $, and if $ S_ {i + 1} <= lim $, then we are able to show $ [lim + 1, lim + S_ {i + 1}] $!

why?

We number Imperial $ S_ {i + 1} $ Required, we expressed to $ [lim + 1, lim + S_ {i + 1}] $ these numbers, we simply use the $ 1 ~ i $ $ shows [lim + 1-S_ {i + 1}, lim] $ to

Account of the requirements $ 1 ~ i $ necessarily shown $ [0, lim] $, and therefore only requires $ lim + 1-S_ {i + 1} \ geq 0 $ to

I.e. $ S_ {i + 1} \ leq lim + 1 $

So if only one inquiry, we can just sweep from front to back

But now he is repeatedly asked ah!

It does not matter, we consider the above condition is equivalent to:

We find that the above operation calculates the answer must be met: the number of all the original set of answers in less sum equal to -1 answer!

So we just need to take advantage of this property

Starting at 1 enumerate an answer, then test interval is less than equal to the sum is greater than the number of answers to this answer

To find the answer to a range of less than equal to the number of and the need for sustainable use of the tree line weights to achieve

Code is well written

#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#define ll long long
#define ls tree[rt].lson
#define rs tree[rt].rson
using namespace std;
const int lim=1000000000;
struct Pre_Seg_Tree
{
    int lson,rson;
    ll sum;
}tree[8000005];
ll v[100005];
int rot[100005];
int n,m,tot;
void update(int rt)
{
    tree[rt].sum=tree[ls].sum+tree[rs].sum;
}
void ins(int &rt,int lrt,int l,int r,ll pos)
{
    rt=++tot;
    if(l==r){tree[rt].sum=tree[lrt].sum+1ll*pos;return;}
    int mid=(l+r)>>1;
    if(pos<=mid)rs=tree[lrt].rson,ins(ls,tree[lrt].lson,l,mid,pos);
    else ls=tree[lrt].lson,ins(rs,tree[lrt].rson,mid+1,r,pos);
    update(rt);
}
ll query(int rt1,int rt2,int l,int r,int lq,int rq)
{
    if(l>=lq&&r<=rq)return tree[rt2].sum-tree[rt1].sum;
    int mid=(l+r)>>1;
    ll s=0;
    if(lq<=mid)s+=query(tree[rt1].lson,tree[rt2].lson,l,mid,lq,rq);
    if(rq>mid)s+=query(tree[rt1].rson,tree[rt2].rson,mid+1,r,lq,rq);
    return s;
}
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'+ CH-10) {c = c *'0';ch=getchar();}
    x=c*f;
}
int main()
{
    read(n);
    for(int i=1;i<=n;i++)read(v[i]),ins(rot[i],rot[i-1],1,lim,v[i]);
    read(m);
    while(m--)
    {
        int l,r;
        read(l),read(r);
        ll ans=1;
        while(1)
        {
            ll sum=query(rot[l-1],rot[r],1,lim,1,ans);
            if(sum<ans)break;
            ans=sum+1;
        }
        printf("%lld\n",ans);
    }
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/zhangleo/p/11088667.html