zoukankan      html  css  js  c++  java
  • BZOJ5319 JSOI2018列队(主席树)

      显然集合后相对位置不变最优。主席树上二分向左和向右的分界点即可。注意主席树的值域。我怎么天天就写点一眼题啊。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<cassert>
    using namespace std;
    #define ll long long
    #define N 500010
    #define V 1500000
    char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
    int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
    int read()
    {
        int x=0,f=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
        while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    int n,m,a[N],root[N],cnt;
    struct data{int l,r,x;ll sum;
    }tree[N<<5];
    void ins(int &k,int l,int r,int x)
    {
        tree[++cnt]=tree[k],k=cnt;tree[k].x++;tree[k].sum+=x;
        if (l==r) return;
        int mid=l+r>>1;
        if (x<=mid) ins(tree[k].l,l,mid,x);
        else ins(tree[k].r,mid+1,r,x);
    }
    int query(int x,int y,int l,int r,int p)
    {
        if (l==r) return l;
        int mid=l+r>>1;
        if (p+tree[tree[y].l].x-tree[tree[x].l].x-1<=mid) return query(tree[x].l,tree[y].l,l,mid,p);
        else return query(tree[x].r,tree[y].r,mid+1,r,p+tree[tree[y].l].x-tree[tree[x].l].x);
    }
    ll sum(int x,int y,int l,int r,int p)
    {
        if (l==r) return tree[y].sum-tree[x].sum;
        int mid=l+r>>1;
        if (p<=mid) return sum(tree[x].l,tree[y].l,l,mid,p);
        else return sum(tree[x].r,tree[y].r,mid+1,r,p)+tree[tree[y].l].sum-tree[tree[x].l].sum;
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("bzoj5319.in","r",stdin);
        freopen("bzoj5319.out","w",stdout);
        const char LL[]="%I64d
    ";
    #else
        const char LL[]="%lld
    ";
    #endif
        n=read(),m=read();
        for (int i=1;i<=n;i++) a[i]=read();
        for (int i=1;i<=n;i++)
        {
            root[i]=root[i-1];
            ins(root[i],0,V,a[i]);
        }
        while (m--)
        {
            int l=read(),r=read(),x=read();
            int p=query(root[l-1],root[r],0,V,x),L=x,R=x+r-l;
            ll ans=(1ll*(L+p)*(p-L+1)>>1)-(1ll*(p+1+R)*(R-p)>>1);
            ans+=tree[root[r]].sum-tree[root[l-1]].sum-(sum(root[l-1],root[r],0,V,p)<<1);
            printf(LL,ans);
        }
        return 0;
    }
  • 相关阅读:
    PS插件安装
    在linux中安装Python
    快慢指针 | 环形链表
    Intel VT-x 支持但处于禁用状态开启
    函数
    连接(交叉连接、内连接、外连接、自连接)
    游标cursor 与循环fetch
    Identity 自增长标识
    Trigger 触发器
    Procedure 存储过程
  • 原文地址:https://www.cnblogs.com/Gloid/p/10123616.html
Copyright © 2011-2022 走看看