zoukankan      html  css  js  c++  java
  • 【BZOJ2138】stone

    题目

    好厉害的题啊

    这道题不难看成一个二分图模型,但是给人一种求最大匹配的感觉,这实在不是很好求的样子,于是自闭了

    但是不妨这样来考虑,对于一个需求(k_i),我们求一个最大的(xleq k_i),使得这张图存在完美匹配就好了,这样我们就能愉快的使用hall定理了

    我们把所有区间排个序,由于保证了没有包含关系,所以左、右端点都是单调的;

    众所周知hall定理要求的是子集,但子集显然不是很好求的样子;而这个题的特殊性质可以使我们只考虑区间的情况,至于为什么,还是比较显然的。

    设第(i)次实际上丢掉了(b_i)个石子,那么为了存在完美匹配,需要时刻满足(sum_{i=l}^rb_ileq sum_{i=fl[l]}^{fr[r]}a_i),利用前缀和把这个狮子打开,即(B_r-B_{l-1}leq A_{fr[r]}-A_{fl[l]-1}),即(B_r-A_{fr[r]}leq B_{l-1}-A_{fl[l]-1})

    假设第(i)操作排序之后在第(j)个位置,那么我们如果要使得这次操作丢出(x)个石子,必须满足(forall kgeq j,t< j,B_{k}+x-A_{fr[k]}leq B_t-A_{fl[t]-1}),即(xleq min(B_t-A_{fl[t]-1})-max(B_{k}-A_{fr[k]}))

    于是我们维护两棵线段树,支持后缀min,前缀max以及区间加就好了

    代码

    #include<bits/stdc++.h>
    #define re register
    inline int read() {
        char c=getchar();int x=0;while(c<'0'||c>'9')c=getchar();
        while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
    }
    const int maxn=5e4+5;
    struct Node{int l,r,t;}q[maxn];
    inline int cmp(const Node A,const Node B) {return A.l<B.l;}
    int n,X,Y,Z,P,c[maxn],b[maxn],A[maxn],pre[maxn],m,K[maxn],ti[maxn],cnt,G[maxn];
    inline int max(int a,int b) {return a>b?a:b;}
    inline int min(int a,int b) {return a<b?a:b;}
    struct Segment_Tree {
        int l[maxn<<2],r[maxn<<2],mx[maxn<<2],mn[maxn<<2],tag[maxn<<2];
        inline void add(int v,int i) {tag[i]+=v;mx[i]+=v,mn[i]+=v;}
        inline void pushup(int i) {
            mx[i]=max(mx[i<<1],mx[i<<1|1]);
            mn[i]=min(mn[i<<1],mn[i<<1|1]);
        }
        inline void pushdown(int i) {
            if(!tag[i]) return;
            add(tag[i],i<<1);add(tag[i],i<<1|1);tag[i]=0;
        }
        void build(int x,int y,int i) {
            l[i]=x,r[i]=y;
            if(x==y) {
                mx[i]=mn[i]=G[x];
                return;
            }
            int mid=x+y>>1;
            build(x,mid,i<<1),build(mid+1,y,i<<1|1);
            pushup(i);
        }
        void change(int x,int y,int v,int i) {
            if(x<=l[i]&&y>=r[i]) {add(v,i);return;}
            pushdown(i);int mid=l[i]+r[i]>>1;
            if(x<=mid) change(x,y,v,i<<1);
            if(y>mid) change(x,y,v,i<<1|1);
            pushup(i);
        }
        int query_mn(int x,int y,int i) {
            if(x<=l[i]&&y>=r[i]) return mn[i];
            pushdown(i);int mid=l[i]+r[i]>>1;
            if(y<=mid) return query_mn(x,y,i<<1);
            if(x>mid) return query_mn(x,y,i<<1|1);
            return min(query_mn(x,y,i<<1),query_mn(x,y,i<<1|1));
        }
        int query_mx(int x,int y,int i) {
            if(x<=l[i]&&y>=r[i]) return mx[i];
            pushdown(i);int mid=l[i]+r[i]>>1;
            if(y<=mid) return query_mx(x,y,i<<1);
            if(x>mid) return query_mx(x,y,i<<1|1);
            return max(query_mx(x,y,i<<1),query_mx(x,y,i<<1|1));
        }
    }T[2];
    int main() {
        n=read(),X=read(),Y=read(),Z=read(),P=read();
        for(re long long i=1;i<=n;i++)
            A[i]=(1ll*(i-X)*(i-X)%P+1ll*(i-Y)*(i-Y)%P+1ll*(i-Z)*(i-Z)%P)%P;
        m=read(),K[1]=read(),K[2]=read(),X=read(),Y=read(),Z=read(),P=read();
        for(re int i=3;i<=m;i++) K[i]=(1ll*K[i-1]*X%P+1ll*K[i-2]*Y%P+Z)%P;
        for(re int i=1;i<=m;i++) q[i].l=read(),q[i].r=read(),q[i].t=i;
        if(!m) return 0;
        std::sort(q+1,q+m+1,cmp);
        for(re int i=1;i<=m;i++) c[q[i].l]++,c[q[i].r+1]--,ti[q[i].t]=i;
        for(re int i=1;i<=n;i++) {
            c[i]+=c[i-1];
            if(c[i]) b[++cnt]=i;
        }
        for(re int i=1;i<=cnt;i++) pre[i]=pre[i-1]+A[b[i]];
        for(re int i=1;i<=m;i++)
            q[i].l=std::lower_bound(b+1,b+cnt+1,q[i].l)-b,q[i].r=std::lower_bound(b+1,b+cnt+1,q[i].r)-b;
        for(re int i=1;i<=m;i++) G[i]=-pre[q[i].r];T[0].build(1,m,1);
        for(re int i=0;i<m;i++) G[i]=-pre[q[i+1].l-1];T[1].build(0,m-1,1);
        for(re int i=1;i<=m;i++) {
            int x=ti[i],nw;
            nw=T[1].query_mn(0,x-1,1)-T[0].query_mx(x,m,1);
            nw=min(K[i],nw);
            T[0].change(x,m,nw,1);T[1].change(x,m-1,nw,1);
            printf("%d
    ",nw);
        }
    }
    
  • 相关阅读:
    easyUI日期框,默认显示今天,今天以后的日期不能选
    vue实现下拉框全选和输入匹配
    【转载】CSS flex属性深入理解
    ES6学习之二
    Centos7(Firewall)防火墙命令
    DeDeCMS模板标签(2)
    DeDeCMS模板标签(1)
    常用js正则表达式大全
    linux yum 命令
    Linux软链接和硬链接
  • 原文地址:https://www.cnblogs.com/asuldb/p/12023975.html
Copyright © 2011-2022 走看看