zoukankan      html  css  js  c++  java
  • 【题解】[LOJ 2736] 「JOISC 2016 Day 3」回转寿司【分块 堆】

    题目链接

    题意

    维护成环的序列 (a)

    • 给定 (A)for i in [l..r]: if a[i]>A: swap(a[i],A),询问 (A) 最后的值。

    询问之间显然不独立。

    (nleq 4 imes 10^5)(mleq 2.5 imes 10^4),9s。

    题解

    分块,对于每一块,用一大根堆维护其内部所有的值,用一小根堆维护其 tag。

    • 整块修改:pop 掉最大值,用 (A) 来替换;并将 (A) 扔进 tag;
    • 重构:从左到右扫过去,尝试用 tag 的堆顶更新 (a_i)
    #include<bits/stdc++.h>
    using namespace std;
    int getint(){
        int ans=0;
        char c=getchar();
        while(c<'0'||c>'9')c=getchar();
        while(c>='0'&&c<='9'){
            ans=ans*10+c-'0';
            c=getchar();
        }
        return ans;
    }
    const int N=4e5+10,B=700;
    
    int a[N];
    int blk,bl[N];
    int n,m;
    struct block{
        int l,r;
        priority_queue<int>val;
        priority_queue<int,vector<int>,greater<int>>tag;
        block():l(0x3f3f3f3f){}
        void rebuild(){
            // while(val.size())val.pop();
            if(tag.empty())return;
            for(int i=l;i<=r;i++){
                if(a[i]>tag.top()){
                    int t=tag.top();tag.pop();
                    tag.push(a[i]);
                    a[i]=t;
                }
            }
        }
        int run(int x){
            tag.push(x);
            val.push(x);
            int t=val.top();
            val.pop();
            return t;
        }
        int run(int l,int r,int x){
            rebuild();
            for(int i=l;i<=r;i++)if(a[i]>x)swap(a[i],x);
            // for(int i=this->l;i<=this->r;i++)val.push(a[i]);
            return x;
        }
    };
    block b[B];
    
    int main(){
        n=getint(),m=getint();
        blk=sqrt(n);
        int bc=n/blk+1;
        for(int i=1;i<=n;i++)bl[i]=i/blk,
                             b[bl[i]].l=min(b[bl[i]].l,i),
                             b[bl[i]].r=max(b[bl[i]].r,i);
        for(int i=1;i<=n;i++){
            a[i]=getint();
            b[bl[i]].val.push(a[i]);
        }
        while(m--){
            int l=getint(),r=getint(),a=getint();
            if(bl[l]==bl[r]&&l<=r){
                a=b[bl[l]].run(l,r,a);
                printf("%d
    ",a);
            }else{
                int lb=(bl[l]+1)%bc,rb=bl[r];
                a=b[bl[l]].run(l,b[bl[l]].r,a);
                while(lb!=rb){
                    a=b[lb].run(a);
                    lb=(lb+1)%bc;
                }
                a=b[bl[r]].run(b[bl[r]].l,r,a);
                printf("%d
    ",a);
            }
        }
    }
    
    
  • 相关阅读:
    创建XNA Shooter游戏——概述
    Android 界面切换与恢复原生界面
    输入和用户界面——SpaceCamera类
    ASP.NET下FCKedit配置及使用参考
    1282. Game Tree 夜
    1122. Game 夜
    1136. Parliament 夜
    hdu 3905 Sleeping 夜
    1195. Ouths and Crosses 夜
    1210. Kind Spirits 夜
  • 原文地址:https://www.cnblogs.com/wallbreaker5th/p/14251720.html
Copyright © 2011-2022 走看看