P4559 [JSOI2018]列队 主席树

Posted bxd123

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P4559 [JSOI2018]列队 主席树相关的知识,希望对你有一定的参考价值。

  题意: 有n个人 每个人有其一开始所在的位置   有m个询问   l r k    问编号为l到r的人填满区间 k----k+r-l  需要的最少距离

 

很容易发现按照原来的相对位置来填k开始的位置肯定是一种最优解

lr的编号区间很容易想到主席树

 

所以问题转化为如何优化主席树的询问   

1、如果遍历每个人 然后累和每个人的距离 肯定会超时  复杂度接近on

2、可以分三种情况讨论

  如果所有的人都在   应到位置的左边  那么贡献为技术图片

  如果所有的人都在    应到位置的右边 那么贡献为 技术图片

 

  否则的话递归到子树继续进行分类

 

学会了主席树一种新的查询方式!!!

技术图片
#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

 

以上是关于P4559 [JSOI2018]列队 主席树的主要内容,如果未能解决你的问题,请参考以下文章

P4559 [JSOI2018]列队

[bzoj5178] [Jsoi2011] 棒棒糖

bzoj5178[Jsoi2011]棒棒糖 主席树

[IOI2018] werewolf 狼人 kruskal重构树,主席树

主席树模板

uoj#402. CTSC2018混合果汁(主席树+二分)