BZOJ4408: [Fjoi 2016]神秘数&&BZOJ4299: Codechef FRBSUM

讲道理这道题的做法还是很神de
对于当前区间扩展可达到[0,max]则一定可以扩展到[0,sum(i)(i<=max+1)]
然后就是用可持久化线段树跑暴力 初始max=0然后一直到不能扩展是max+1即为答案

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
using namespace std;
struct Seg
{int l,r,data;Seg *lc,*rc;Seg(){lc=rc=NULL;}}
*Tree[1000001];
Seg *empty;

inline void Bg()
{
    empty=new Seg;
    empty->lc=empty;
    empty->rc=empty;
    empty->data=0;
}

inline Seg *NewSeg()
{
    Seg *tp=new Seg;
    tp->lc=empty,tp->rc=empty;
    tp->data=0;return tp;
}
Seg *Change(Seg*Old,int l,int r,int P)
{
    Seg *res;
    if(l^r)
    if(Old==empty)
      {
        res=NewSeg();
        res->l=l,res->r=r,res->data+=P;
        int Mid=l+r>>1;
        if(Mid<P)
           res->rc=Change(empty,Mid+1,r,P);
        else 
           res->lc=Change(empty,l,Mid,P);
        return res;
      }
      else
      {
        res=NewSeg();
        *res=*Old;
        res->data+=P;
        int Mid=l+r>>1;
        if(Mid<P)
           res->rc=Change(Old->rc,Mid+1,r,P);
        else 
           res->lc=Change(Old->lc,l,Mid,P);
        return res;

      }
    else
     {
      res=NewSeg();
      if(Old!=empty)*res=*Old;
      res->l=l,res->r=r;
      res->data+=P;
      return res;
    }
}
int Query(Seg*Old,Seg*New,int r)
{
    if(New->r<=r)   
    return New->data-Old->data;
    int Mid=New->l+New->r>>1;
    int res=0;
    if(Mid<r)
       if(New->rc!=empty)
         res+=Query(Old->rc,New->rc,r);
    if(New->lc!=empty)
         res+=Query(Old->lc,New->lc,r);
    return res;          
}
char c;
inline void read(int &a)
{
    a=0;do c=getchar();while(c<'0'||c>'9');
    while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();
}
int main()
{

    Bg();
    Tree[0]=NewSeg();
    Tree[0]->l=0,Tree[0]->r=1000000001;
    Tree[0]->data=0;
    int n,m;
    int i,j,k,ma=0,last=1;
    read(n);
    for(i=1;i<=n;i++)
      read(j),Tree[i]=Change(Tree[i-1],0,Tree[i-1]->r,j);
    read(m);
    for(i=1;i<=m;i++)
       {
        read(j),read(k);
        if(j>k)swap(j,k);
        ma=0,last=1;
        while(ma^last)
        {
            last=ma;
            ma=Query(Tree[j-1],Tree[k],ma+1);
        }
        printf("%d\n",ma+1);
       }
    return 0;
}

你可能感兴趣的:(BZOJ4408: [Fjoi 2016]神秘数&&BZOJ4299: Codechef FRBSUM)