zoukankan      html  css  js  c++  java
  • AT3673 [ARC085D] NRE 题解

    AT3673 [ARC085D] NRE 题解

    Problem

    ​ 给定一个全为(0)的数组(A),给一个数组(B)(m)个操作,每个操作将数组(A)指定区间改成(1),问合理选择部分操作后使得两个数组的(sum[A_i eq B_i])最小。

    Solution

    ​ 考虑把这个式子变形一下:

    [sum[A_i eq B_i] \ ightarrow sum[A_i=0][B_i=1]+sum[A_i=1][B_i=0] \ ightarrow sum[A_i=0]+sum[B_i=0]([A_i=1]-[A_i=0]) ]

    ​ 第一项([A_i=0])是个定值,(([A_i=1]-[A_i=0]))也只和(A)有关,所以现在要考虑的只有([B_i=0])

    ​ 考虑DP,设(f_i)表示前(i)个中上式的最小值。首先可以从(f_i)转移到(f_{i+1}),表示不选以(i)为左端点的区间,要么可以转移到右端点

    Code

    #include<bits/stdc++.h>
    using namespace std;
    
    vector<int>L[200005];
    
    int n,m,Ans;
    
    int A[200005];
    
    struct Segment_Tree{
    
        #define ls k<<1|0
        #define rs k<<1|1
        #define inf 0x3f3f3f3f
    
        int tag[800005],Min[800005];
    
        inline void Pushup(int k){
            Min[k]=min(Min[ls],Min[rs]);
        }
    
        inline void Pushdown(int k){
            if(tag[k]){
                tag[ls]+=tag[k];
                tag[rs]+=tag[k];
                Min[ls]+=tag[k];
                Min[rs]+=tag[k];
                tag[k];
            }
            return;
        }
    
        void Initialize(){
            memset(Min,0x3f,sizeof Min);
        }
    
        void Insert(int k,int l,int r,int pos,int val){
            if(l==r){
                Min[k]=min(Min[k],val);
                return;
            }
            Pushdown(k);
            int mid=l+r>>1;
            if(pos<=mid)
                Insert(ls,l,mid+0,pos,val);
            else
                Insert(rs,mid+1,r,pos,val);
            return Pushup(k);
        }
    
        void Change(int k,int l,int r,int wl,int wr,int val){
            if(wl> r||l> wr)
                return;
            if(wl<=l&&r<=wr){
                tag[k]+=val;
                Min[k]+=val;
                return;
            }
            Pushdown(k);
            int mid=l+r>>1;
            Change(ls,l,mid+0,wl,wr,val);
            Change(rs,mid+1,r,wl,wr,val);
            return Pushup(k);
        }
    
        int query(int k,int l,int r,int wl,int wr){
            if(wl> l||l> wr)    
                return inf;
            if(wl<=l&&r<=wr)
                return Min[k];
            Pushdown(k);
            int res=inf,mid=l+r>>1;
            res=min(res,query(ls,l,mid+0,wl,wr));
            res=min(res,query(rs,mid+1,r,wl,wr));
            return res;
        }
    
        #undef ls
        #undef rs
        #undef inf
    
    }T;
    
    inline int read(){
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){
           if(ch=='-')f=-1;
           ch=getchar();
        }
        while(ch>='0'&&ch<='9'){
           x=(x<<1)+(x<<3)+ch-'0';
           ch=getchar();
        }
        return x*f;
    }
    
    int main(){
        
        n=read();
    
        for(register int i=1;i<=n;++i)
            A[i]=read();
        
        m=read();
    
        for(register int i=1;i<=m;++i){
            int l=read();
            int r=read();   
            L[l].push_back(r);
        }
    
        T.Initialize();
    
        T.Insert(1,0,n,0,0);
    
        for(register int i=1;i<=n;++i){
            int N=L[i].size();
            for(register int k=0;k<N;++k){
                int Min=T.query(1,0,n,0,L[i][k]);
                T.Insert(1,0,n,L[i][k],Min);
            }
            T.Change(1,0,n,0,i-1,A[i]?+1:-1);
            Ans+=(A[i]==0);
        }
    
        printf("%d
    ",Ans+T.query(1,0,n,0,n));
    
        return 0;
    }
    
  • 相关阅读:
    如何设置 ComboBox 下拉列表的高度或间距
    winform中ComboBox利用AutoComplete属性实现模糊查询(有缺陷)
    C#中combobox 控件属性、事件、方法
    ComboBox TextUpdate事件
    C#判断页面中的多个文本框输入值是否有重复的实现方法
    c# winfrom程序中 enter键关联button按钮
    WinForm 中ComboBox 绑定总结
    c# 实现ComboBox自动模糊匹配
    C#中ComboBox动态绑定赋值
    WinForm 中 comboBox控件之数据绑定
  • 原文地址:https://www.cnblogs.com/zjy123456/p/14055427.html
Copyright © 2011-2022 走看看