zoukankan      html  css  js  c++  java
  • Bzoj3932--Cqoi2015任务查询系统

    按时间来建一棵主席树

    下一个时间和上一个时间的改变就是那个时间点任务的改变

    具体我们可以把任务拆成两个时间点,前一个代表加上这个数,后一个是删除这个数

    代码:

    #include<bits/stdc++.h>
    #define MAXN 100005
    #define MOD 1000000007
    #define LINF 100000000000000ll
    #define INF 1000000000
    #define LL long long 
    using namespace std;
    
    inline int _abs(int a) {return a>0?a:-a;}
    
    const int mp=10000000;
    struct event{
        int pos,k;
        bool operator < (event b) const {
            return pos<b.pos;
        }
        inline void in(int a,int b) {
            pos=a;k=b;
        }
    }ev[MAXN*3];
    int m,n;
    
    namespace Chairman_Tree{
        const int L=0,R=1;
        int root[MAXN],sz;
        struct Node{
            int s,son[2],sum;
        }x[MAXN*70];
        
        void Build_Tree(int l,int r,int &now,int fr,int v,int p,bool c) {
            if(c) now=++sz,x[now]=x[fr];
            x[now].s+=p;x[now].sum+=p*v;
            if(l==r) return;
            int mid=l+r>>1;
            if(v>mid) Build_Tree(mid+1,r,x[now].son[R],x[fr].son[R],v,p,x[now].son[R]==x[fr].son[R]);
            else Build_Tree(l,mid,x[now].son[L],x[fr].son[L],v,p,x[now].son[L]==x[fr].son[L]);
        }
        void Build(int x,int y,int p,bool c) {
            Build_Tree(1,mp,root[x],root[y],_abs(p),p>0?1:-1,c);
        }
        
        LL Query(int pos,int k) {
            LL ret=0;
            int now=root[pos],l=1,r=mp,mid;
            if(k>=x[now].s) return x[now].sum;
            while(l!=r) {
                mid=l+r>>1;
                if(x[x[now].son[L]].s<k) k-=x[x[now].son[L]].s,ret+=x[x[now].son[L]].sum,now=x[now].son[R],l=mid+1;
                else now=x[now].son[L],r=mid;
            }
            return ret+k*l;
        }
    }
    
    using namespace Chairman_Tree;
    
    int main() {
        scanf("%d%d",&m,&n);
        for(int a,b,c,i=1;i<=m;i++) {
            scanf("%d%d%d",&a,&b,&c);
            ev[(i<<1)-1].in(a,c);
            ev[i<<1].in(b+1,-c);
        }
        sort(ev+1,ev+1+2*m);
        for(int now=1,i=1;i<=n;i++) {
            root[i]=++sz;
            x[root[i]]=x[root[i-1]];
            while(ev[now].pos==i) Build(i,i-1,ev[now].k,0),now++;
        }
        for(LL pos,a,b,c,pre=1,i=1;i<=n;i++) {
            scanf("%lld%lld%lld%lld",&pos,&a,&b,&c);
            a=1+(a*pre+b)%c;
            pre=Query(pos,a);
            printf("%lld
    ",pre);
        }
        return 0;
    }
  • 相关阅读:
    C语言知识
    Java课程设计——个人
    Java大作业
    DAO模式代码阅读及应用
    有理数设计
    泛型 -Java
    集合框架之ArrayList -Java
    图总结
    树、二叉树、查找算法总结
    编辑器、编译器、文件、IDE等常见概念辨析
  • 原文地址:https://www.cnblogs.com/ihopenot/p/5942222.html
Copyright © 2011-2022 走看看