zoukankan      html  css  js  c++  java
  • Loj6515「雅礼集训 2018 Day10」贪玩蓝月(线段树分治)

    这是基于时间的离线线段树分治法,时间分治是一种经典套路,一般来说,离线算法比在线算法容易实现。

    因此在本题,我们用双端队列维护信息,弹出来的时候,在时间线段树上区间修改,表示他在哪段时间可见,这样我们查询的时候,在所需要查询的时间,那里就是合法的信息

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    typedef pair<pair<int,int>,int> plll;
    const int N=1e5+10;
    const int mod=1e9+7;
    int m,p;
    struct node{
        int l,r;
        vector<pll> num;
    }tr[N<<2];
    pll ans[N];
    int vis[N];
    ll f[N][550];
    int cnt;
    void build(int u,int l,int r){
        if(l==r){
            tr[u]={l,r};
        }
        else{
            tr[u]={l,r};
            int mid=l+r>>1;
            build(u<<1,l,mid);
            build(u<<1|1,mid+1,r);
        }
    }
    void modify(int u,int l,int r,pll x){
        if(tr[u].l>=l&&tr[u].r<=r){
            tr[u].num.push_back(x);
            return ;
        }
        int mid=tr[u].l+tr[u].r>>1;
        if(l<=mid)
            modify(u<<1,l,r,x);
        if(r>mid)
            modify(u<<1|1,l,r,x);
    }
    void query(int u){
        int tmp=cnt;
        int i,j;
        for(i=0;i<(int)tr[u].num.size();i++){
            for(j=0;j<p;j++){
                //相加永远不可能超过2p,所以不用担心是否会遗漏情况,直接更新即可
               f[cnt+i+1][(j+tr[u].num[i].first)%p]=max(f[cnt+i][(j+tr[u].num[i].first)%p],f[cnt+i][j]+tr[u].num[i].second);
            }
        }
        cnt+=(int)tr[u].num.size();
        if(tr[u].l==tr[u].r){
            if(vis[tr[u].l]){
                ll res=-0x3f3f3f3f;
                for(int i=ans[tr[u].l].first;i<=ans[tr[u].r].second;i++){
                    res=max(res,f[cnt][i]);
                }
                if(res==-0x3f3f3f3f){
                    cout<<-1<<endl;
                }
                else{
                    cout<<res<<endl;
                }
            }
            cnt=tmp;
            return ;
        }
        query(u<<1);
        query(u<<1|1);
        cnt=tmp;
    }
    int main(){
        ios::sync_with_stdio(false);
        int d;
        cin>>d;
        cin>>m>>p;
        build(1,1,m);
        int i;
        deque<plll> q;
        for(i=1;i<=m;i++){
            string s;
            cin>>s;
            int a,b;
            if(s=="IF"){
                cin>>a>>b;
                q.push_front({{a%p,b},i});
            }
            else if(s=="IG"){
                cin>>a>>b;
                q.push_back({{a%p,b},i});
            }
            else if(s=="DF"){
                modify(1,q.front().second,i-1,q.front().first);
                q.pop_front();
            }
            else if(s=="DG"){
                modify(1,q.back().second,i-1,q.back().first);
                q.pop_back();
            }
            else{
                cin>>a>>b;
                vis[i]=1;
                ans[i]={a,b};
            }
        }
        while(q.size()){
            auto tmp=q.front();
            q.pop_front();
            modify(1,tmp.second,m,tmp.first);
        }
        memset(f,-0x3f,sizeof f);
        f[0][0]=0;
        query(1);
    }
    View Code
    没有人不辛苦,只有人不喊疼
  • 相关阅读:
    java:字符串(下)
    java字符串(上)
    Java流程控制:循环语句
    JAVA学习笔记(二十三)
    JAVA学习笔记(二十二)
    JAVA学习笔记(二十一)
    JAVA学习笔记(二十)
    JAVA学习笔记(十九)
    JAVA学习笔记(十八)
    JAVA学习笔记(十七)
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/14120156.html
Copyright © 2011-2022 走看看