zoukankan      html  css  js  c++  java
  • BZOJ3932(主席树上二分+差分

    按时间作为主席树的版本,每个版本的主席树都是一个权值线段树。

    差分消去时间影响

    对于当前时间版本的主席树查询前K大即可。

    树上二分时结束后切记判定l==r的状态(易错

    l==r叶子节点可能存在多个值(值大小为sum/siz )

    用I64dOLE了好久 。。 。。。。 。 。。 。 。 。 。 。 。 。 。。 。 

    用bit/stdc++.h  CE.....

    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int N = 301500;
    const int LOGN = 35;
    const int maxn = N*LOGN;
    #define lson son[rt][0]
    #define rson son[rt][1]
    #define un(x) (x>0?x:-x)
    struct node{
        int pos,val;
    };
    node cf[N<<1];
    ll sum[maxn],siz[maxn];
    int son[maxn][2],root[N],id[N];
    void pushup(int rt)
    {
        siz[rt] = siz[lson]+siz[rson];
        sum[rt] = sum[lson]+sum[rson];
    }
    int tot = 0;
    void update(int x,int& y,int l,int r,int p)
    {
        y = ++tot;
        if(l==r)
        {
            if(p>0) siz[y] = siz[x]+1;
            else siz[y] = siz[x]-1;
            sum[y] = sum[x]+p;
            return ;
        }
        son[y][0] = son[x][0];
        son[y][1] = son[x][1];
        int m = (r+l)>>1;
        if(un(p)<=m) update(son[x][0],son[y][0],l,m,p);
        else update(son[x][1],son[y][1],m+1,r,p);
        pushup(y);
    
    }
    ll  bfind(int l,int r,int rt,int k)
    {
        //cout<<"size:: "<<siz[rt]<<sum[rt]<<endl;
        if(siz[rt]<=k) return sum[rt];
        ll ans = 0;
        while(l<r)
        {
            int m = (r+l)>>1;
            if(k<siz[lson])
            {
                r = m;
                rt = lson;
            }
            else{
                l = m+1;
                k -= siz[lson];
                ans+=sum[lson];
                rt = rson;
            }
        }
        if(k&&siz[rt]>0) ans+=sum[rt]/siz[rt]*min(k,siz[rt]);
        return ans;
    }
    bool cmp(node a,node b)
    {
        return a.pos<b.pos;
    }
    int main()
    {
        int n,m;
        scanf("%d%d",&m,&n);
        int s,e,p;
        int lim = 0;
        int cnt = 0;
        for(int i=0;i<m;i++){
            scanf("%d%d%d",&s,&e,&p);
            cf[++cnt] = (node){s,p};
            cf[++cnt] = (node){e+1,-p};
            lim = max(lim,p);
        }
        sort(cf+1,cf+cnt+1,cmp);
        ll pre = 1;
        for(int i=1;i<=cnt;i++)update(root[i-1],root[i],1,lim,cf[i].val);
        for(int i=cnt;i>=1;i--){
            if(cf[i].pos!=cf[i+1].pos) id[cf[i].pos] = i;
        }
        for(int i=1;i<=n;i++){
            if(id[i]==0)id[i] = id[i-1];
            //cout<<id[i]<<endl;
        }
        int x,a,b,c,k;
        for(int i=0;i<n;i++)
        {
            scanf("%d%d%d%d",&x,&a,&b,&c);
            k = (a*pre+b)%c+1;
            pre = bfind(1,lim,root[id[x]],k);
            //cout<<x<<"  "<<id[x]<<" ";
            printf("%lld
    ",pre);
        }
        return 0;
    }
    AC代码
  • 相关阅读:
    叶子的染色
    旅游规划
    加分二叉树
    皇宫看守
    战略游戏
    《C/C++/Java/Pascal 程序设计基础》习题集 解题2
    《C/C++/Java/Pascal 程序设计基础》习题集 解题1
    中国大学MOOC-翁恺-C语言程序设计习题集 08-2 到 10-2
    中国大学MOOC-翁恺-C语言程序设计习题集 10-3 到 11-1
    中国大学MOOC-翁恺-C语言程序设计习题集 07-0 到 08-1
  • 原文地址:https://www.cnblogs.com/Geek-xiyang/p/7348126.html
Copyright © 2011-2022 走看看