P4559 [JSOI2018] tree lined Chairman

  There are at least n individuals from every person has one start position where there are m asking lrk numbered l to r asking people to fill the interval k ---- k + rl need: meaning of the questions

 

It is easy to find location in accordance with the relative position of the original to fill k certainly a start of the optimal solution

lr numbering range is easy to think of the Chairman of the tree

 

So the question into how to optimize queries Chairman tree   

1, if the person then through each and everyone's tired from overtime will definitely close on complexity

2, can be divided into three cases discussed

  If you left all of them should be in the position to contribute to it

  If the right of all people to be in a position to contribute so 

 

  Otherwise recursive subtree continue to be classified

 

Chairman tree learn a new query! ! !

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define ll long long
#define see(x) (cerr<<(#x)<<'='<<(x)<<endl)
#define pb push_back
#define inf 0x3f3f3f3f
#define CLR(A,v)  memset(A,v,sizeof A)
typedef pair<int,int>pii;
//////////////////////////////////
const int N=1e6+10;
int T[N],lson[N<<5],rson[N<<5],ncnt,n,m;
ll t[N<<5],sum[N<<5];
void upnode(int x,int l,int r,int pre,int &pos)
{
    pos=++ncnt;
    lson[pos]=lson[pre];rson[pos]=rson[pre];
    t[pos]=t[pre]+1;
    sum[pos]=sum[pre]+x;
    int m=(l+r)>>1;
    if(l==r)return ;
    if(x<=m)upnode(x,l,m,lson[pre],lson[pos]);
    else upnode(x,m+1,r,rson[pre],rson[pos]);
}
ll qsum(int L,int R,int l,int r,int pre,int pos)
{   
    if(L>R)return 0;
    if(r<=L)return 1ll*(L+R)*(R-L+1)/2-(sum[pos]-sum[pre]);
    if(l>=R)return  (sum[pos]-sum[pre])-1ll*(L+R)*(R-L+1)/2;
    if(l==r)return 0;int m=(l+r)>>1;
    int peo=t[lson[pos]]-t[lson[pre]];
    return qsum(L,L+peo-1,l,m,lson[pre],lson[pos])+qsum(L+peo,R,m+1,r,rson[pre],rson[pos]);
}
int main()
{
    scanf("%d%d",&n,&m);int x;
    rep(i,1,n)scanf("%d",&x),upnode(x,1,1e6,T[i-1],T[i]);
    int l,r,k;
    while(m--)
    {
        scanf("%d%d%d",&l,&r,&k);
        printf("%lld\n",qsum(k,k+r-l,1,1e6,T[l-1],T[r]));
    }
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/bxd123/p/11562975.html