zoukankan      html  css  js  c++  java
  • BZOJ5462 APIO2018新家(线段树+堆)

      一个显然的做法是二分答案后转化为查询区间颜色数,可持久化线段树记录每个位置上一个同色位置,离线后set+树状数组套线段树维护。这样是三个log的。

      注意到我们要知道的其实只是是否所有颜色都在该区间出现,可以改为查询后缀区间的上一个同色位置中最小的。这样我们就只需要set+线段树就可以维护了,同样二分答案是两个log。直接在线段树上二分就变成了一个log。

      给每种颜色在坐标-inf和inf处加点来避免乱七八糟的讨论。离散化一下。对于相同坐标的点,在叶子维护堆即可。调过样例就能1A了。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<set>
    #include<queue>
    #include<vector>
    using namespace std;
    #define ll long long
    #define N 600010
    #define inf 600000003
    char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
    int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
    int read()
    {
        int x=0,f=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
        while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    int n,m,q,t,L[N<<2],R[N<<2],tree[N<<2],ans[N],u[N];
    struct data
    {
        int x,t,op;int p,i;
        bool operator <(const data&a) const
        {
            return t<a.t||t==a.t&&abs(op)>abs(a.op);
        }
    }a[N<<2];
    priority_queue<int,vector<int>,greater<int> > ins[N<<2],del[N<<2];
    multiset<int> color[N];
    void build(int k,int l,int r)
    {
        L[k]=l,R[k]=r;tree[k]=inf;
        if (l==r) return;
        int mid=l+r>>1;
        build(k<<1,l,mid);
        build(k<<1|1,mid+1,r);
    }
    int query(int k,int l,int r,int x,int last)
    {
        if (L[k]==R[k]) return max(u[L[k]]-x,x-last);
        int mid=L[k]+R[k]>>1;
        if (r<=mid) return query(k<<1,l,r,x,min(tree[k<<1|1],last));
        else if (l>mid) return query(k<<1|1,l,r,x,last);
        else
        {
            if (u[mid]-x>x-min(last,tree[k<<1|1])) return query(k<<1,l,mid,x,min(last,tree[k<<1|1]));
            else return min(x-min(last,tree[k<<1|1]),query(k<<1|1,mid+1,r,x,last));
        }
    }
    void modify(int k,int p,int x,int op)
    {
        if (L[k]==R[k])
        {
            if (op==1) ins[k].push(x);else del[k].push(x);
            while (!del[k].empty()&&ins[k].top()==del[k].top()) ins[k].pop(),del[k].pop();
            tree[k]=ins[k].empty()?inf:ins[k].top();
            return;
        }
        int mid=L[k]+R[k]>>1;
        if (p<=mid) modify(k<<1,p,x,op);
        else modify(k<<1|1,p,x,op);
        tree[k]=min(tree[k<<1],tree[k<<1|1]);
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("bzoj5462.in","r",stdin);
        freopen("bzoj5462.out","w",stdout);
        const char LL[]="%I64d
    ";
    #else
        const char LL[]="%lld
    ";
    #endif
        n=read(),m=read(),q=read();
        for (int i=1;i<=n;i++)
        {
            int x=read(),y=read(),l=read(),r=read();
            t++;a[t].x=x,a[t].t=l,a[t].op=1,a[t].p=y;
            t++;a[t].x=x,a[t].t=r+1,a[t].op=-1,a[t].p=y;
            u[i]=x;
        }
        for (int i=1;i<=q;i++) t++,a[t].x=read(),a[t].t=read(),a[t].op=0,a[t].p=0,a[t].i=i,u[n+i]=a[t].x;
        sort(u+1,u+n+q+1);int v=unique(u+1,u+n+q+1)-u-1;u[0]=-inf,u[++v]=inf;
        for (int i=1;i<=t;i++) a[i].x=lower_bound(u,u+v+1,a[i].x)-u;
        build(1,0,v);
        sort(a+1,a+t+1);
        //for (int i=1;i<=t;i++) cout<<a[i].x<<' '<<a[i].t<<' '<<a[i].op<<' '<<a[i].p<<' '<<a[i].i<<endl;
        for (int i=1;i<=m;i++)
        {
            color[i].insert(0),color[i].insert(v);
            modify(1,v,-inf,1);
        }
        for (int i=1;i<=t;i++)
        if (a[i].op==0) ans[a[i].i]=query(1,a[i].x,v,u[a[i].x],inf);
        else if (a[i].op==-1)
        {
            multiset<int>::iterator it=color[a[i].p].find(a[i].x);
            it++;int x=*it;
            it--,it--;int y=*it;
            it++;color[a[i].p].erase(it);
            modify(1,x,u[a[i].x],-1),modify(1,a[i].x,u[y],-1),modify(1,x,u[y],1);
        }
        else
        {
            multiset<int>::iterator it=color[a[i].p].lower_bound(a[i].x);
            int x=*it;
            it--;int y=*it;
            color[a[i].p].insert(a[i].x);
            modify(1,x,u[a[i].x],1),modify(1,a[i].x,u[y],1),modify(1,x,u[y],-1);
        }
        for (int i=1;i<=q;i++) printf("%d
    ",ans[i]>inf/3?-1:ans[i]);
        return 0;
    }
  • 相关阅读:
    68
    56
    Django manager 命令笔记
    Django 执行 manage 命令方式
    Django 连接 Mysql (8.0.16) 失败
    Python django 安装 mysqlclient 失败
    H.264 SODB RBSP EBSP的区别
    FFmpeg—— Bitstream Filters 作用
    MySQL 远程连接问题 (Windows Server)
    MySQL 笔记
  • 原文地址:https://www.cnblogs.com/Gloid/p/10140787.html
Copyright © 2011-2022 走看看