• hdu5140 Hun Gui Wei Company题解 主席树


    题目链接

    这个题还是比较模板的。等级和年限这两个参数,一个当成下标,一个当成值域(应该是这么叫的吧)。

    假设以level为下标建立主席树,age作为值域,那我们可以把所有员工的level离散化。因为这个题强制在线,我们没有办法把查询的level离散化,但是我们可以每次二分,找到这个询问对应着的范围。我偷懒没有离散化age,写的动态开点。

    需要注意的几个点:

    • 模板要写对,我因为这个调了一整天。
    • 还有二分的问题,算是个小套路,大家都知道lower_bound(a+1,a+n+1,x)-a,二分最后一个<=x的数可以用upper_bound(a+1,a+n+1,x)-a-1。这两个式子的取值范围分别是\([1,n+1]\)\([0,n]\)

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    typedef pair<int,int> pii;
    #define forg(i,x) for(int i=first[x];i;i=nxt[i])
    #define forl(z,i,x) for(int i=z.first[x],y=z.to[i];i;i=z.nxt[i],y=z.to[i])
    #define uu unsigned
    #define fi first
    #define se second
    #define ran() ((unsigned)rand())
    #define lam(z,k) [&](const z &a,const z &b){ return k; }
    #define od(x) ((x)&1)
    #define ev(x) (od(x)^1)
    
    #define lson(x) tr[x].lson
    #define rson(x) tr[x].rson
    const int mxn=1e5+3,mxm=mxn,siz=1e9;const long long cc=1e17;
    int n,m,nn;
    struct worker{ 
        int gz,dj,tm;//工资 等级 时间
    }a[mxn];
    int lsd[mxn];
    inline int getls(int x){
        return lower_bound(lsd+1,lsd+nn+1,x)-lsd;
    }
    class zxs{
        public:
        struct a_w{
            int lson,rson;
            long long sum;
        }tr[mxn*50];
        int RT[mxn],tot;
        inline void clear(){
            memset(RT,0,sizeof(RT));
            for(int i=1;i<=tot;++i)tr[i].sum=lson(i)=rson(i)=0;
            tot=0;
        }
        inline void dadd(int &p,int pre,int l,int r,int pc,int kc){
    //单点修改
            int mid=(l+r)>>1;
            if(p==0||p==pre){
                p=++tot; if(pre)tr[p]=tr[pre];
                
            }
            if(l==r)return tr[p].sum+=kc,void();
            if(pc<=mid)dadd(lson(p),lson(pre),l,mid,pc,kc);
            else dadd(rson(p),rson(pre),mid+1,r,pc,kc);
            pushup(p);
        }
        inline void pushup(int x){
            tr[x].sum=tr[lson(x)].sum+tr[rson(x)].sum;
        }
        inline long long ask(int x1,int x2,int l,int r,int lc,int rc){
            int mid=(l+r)>>1;
            if(!x1&&!x2)return 0;
            if(lc<=l&&r<=rc)return tr[x2].sum-tr[x1].sum;
            long long res=0;
            if(lc<=mid)res+=ask(lson(x1),lson(x2),l,mid,lc,rc);
            if(rc>mid)res+=ask(rson(x1),rson(x2),mid+1,r,lc,rc);
            return res;
        }
    }seg;
    
    class hah{public:void a(){b();}void b(){a();}}emm;
    inline int getdj2(int x){
        int l=0,r=nn,mid;
        while(l!=r){
            mid=(l+r+1)>>1;
            if(lsd[mid]<=x)l=mid;
            else r=mid-1;
        }
        return l;
    }
    
    int main(){
        while(~scanf("%d",&n)){
            seg.clear();
            for(int i=1;i<=n;++i)scanf("%d%d%d",&a[i].gz,&a[i].dj,&a[i].tm),lsd[i]=a[i].dj;
            scanf("%d",&m);
            sort(lsd+1,lsd+n+1);nn=unique(lsd+1,lsd+n+1)-(lsd+1);
            for(int i=1;i<=n;++i)a[i].dj=getls(a[i].dj);
            sort(a+1,a+n+1,lam(worker,a.dj<b.dj));
            
            
            for(int i=1,p=1;i<=nn&&p<=n;++i){
                int &kk=seg.RT[i];
                for(;a[p].dj==i&&p<=n;++p){
                    seg.dadd(kk,seg.RT[i-1],1,siz+1,a[p].tm+1,a[p].gz);
                }
                if(!kk)kk=seg.RT[i-1];//这句可以省略,因为离散化以后是连续的
            }
            
            lsd[0]=-233,lsd[nn+1]=siz+233;
            
            long long lstans=0;
    
            for(int i=1;i<=m;++i){
                static long long dj1,dj2,tm1,tm2;scanf("%lld%lld%lld%lld",&dj1,&dj2,&tm1,&tm2);
                dj1+=lstans,dj2-=lstans,tm1+=lstans,tm2-=lstans;
                if(dj1>dj2)swap(dj1,dj2);if(tm1>tm2)swap(tm1,tm2);
                dj1=max(dj1,0ll),tm1=max(tm1,0ll),dj2=min(dj2,(long long)siz),tm2=min(tm2,(long long)siz);
                if(dj1>dj2){puts("0");lstans=0;continue;}//特判
                int aa=dj1,bb=dj2;
                dj1=getls(dj1),dj2=upper_bound(lsd+1,lsd+nn+1,dj2)-lsd-1;//getdj2(dj2)
                if(!(lsd[dj1]>=aa&&lsd[dj1-1]<aa && lsd[dj2]<=bb&&lsd[dj2+1]>bb))return puts("whatawht"),emm.a(),33333;
    //检查二分的结果是否合法 这句不加也可以
                // first>=dj1 last<=dj2
                
                if(dj1>dj2||tm1>tm2){puts("0");lstans=0;continue;}//特判
                printf("%lld\n",lstans= seg.ask(seg.RT[dj1-1],seg.RT[dj2],1,siz+1,tm1+1,tm2+1));
            }
        }
        return 0;
    }
    
  • 相关阅读:
    hdu2049
    hdu2047
    hdu2568
    hdu2570
    推流摄像头推RTMP视频流至EasyDSS视频直播点播平台Chrome浏览器无法播放如何解决?
    RTMP推流协议视频智能分析/人脸识别/直播点播平台EasyDSS接口调用注意事项介绍
    【解决方案】人脸识别/智能分析视频安防服务平台EasyCVR如何打造智慧人社局培训办事机构远程监控系统?
    【解决方案】RTMP推流协议视频智能分析/直播点播/人脸识别平台EasyDSS打造智能多媒体展厅解决方案
    【解决方案】视频智能分析/人脸识别平台EasyDSS实现景区智慧旅游体系,VR+大数据打造风景区实时视频
    RTMP推流协议视频智能分析平台EasyDSS直播点播系统新版本无法完成推流以及录像回看排查过程
  • 原文地址:https://www.cnblogs.com/happyguy/p/13364252.html
Copyright © 2020-2023  润新知