zoukankan      html  css  js  c++  java
  • D. Trash Problem 线段树

    D. Trash Problem 线段树

    题目大意:

    (n) 堆物品,第 (i) 堆物品在位置 (p_i),每次你可以选择移动一堆物品到另一堆,代价是他们距离的绝对值,问最少的代价使得最后只剩下两堆物品。你有两种操作,每次操作之后输出最小的代价。

    • 0 x 表示把 (x) 这个位置的物品移除,保证 (x) 这个位置有物品
    • 1 x 表示把 (x) 这个位置加上物品,保证 (x) 这个位置此时没有物品

    题解:

    • 很容易发现,最后答案就是 最大位置与最小位置的绝对值 减去 相邻区间绝对值最大的这个值。
    • 然后这些都可以用线段树维护,最大值最小值就是很普通的线段树。
    • 线段树在往上传递的过程 维护相邻区间绝对值最大即可
    #include <bits/stdc++.h>
    #define lson (id<<1)
    #define rson (id<<1|1)
    #define inf 0x3f3f3f3f
    using namespace std;
    const int maxn = 2e5 + 10;
    typedef long long ll;
    int p[maxn],a[maxn],t[maxn];
    int v[maxn<<2],maxs[maxn<<2],Max[maxn<<2],Min[maxn<<2];
    void push_up(int id) {
        Min[id] = min(Min[lson], Min[rson]);
        Max[id] = max(Max[lson], Max[rson]);
        maxs[id] = max(maxs[lson], maxs[rson]);
        if (Min[rson] < inf && Max[lson] > 0) maxs[id] = max(maxs[id], Min[rson] - Max[lson]);
    }
    void update(int id,int l,int r,int pos,int f){
    //    printf("update:id = %d l = %d r = %d pos = %d f = %d
    ",id,l,r,pos,f);
        if(l==r){
            if(f) Max[id] = Min[id] = v[l];
            else Max[id] = 0,Min[id] = inf;
            maxs[id] = 0;
            return ;
        }
        int mid = (l+r)>>1;
        if(pos<=mid) update(lson,l,mid,pos,f);
        else update(rson,mid+1,r,pos,f);
        push_up(id);
    }
    int main(){
        int N,M,now = 0;
        scanf("%d%d",&N,&M);
        memset(Min,inf,sizeof(Min));
        for(int i=1;i<=N;i++) scanf("%d",&p[i]),v[++now] = p[i];
        for(int i=1;i<=M;i++) scanf("%d%d",&t[i],&a[i]),v[++now] = a[i];
        sort(v+1,v+1+now);
        now = unique(v+1,v+1+now) - v - 1;
        for(int i=1;i<=N;i++){
            int pos = lower_bound(v+1,v+1+now,p[i]) - v;
            update(1,1,now,pos,1);
        }
        int ans = max(0,Max[1] - Min[1] - maxs[1]);
        printf("%d
    ",ans);
        for(int i=1;i<=M;i++){
            int pos = lower_bound(v+1,v+1+now,a[i]) - v;
            update(1,1,now,pos,t[i]);
            ans = max(0,Max[1] - Min[1] - maxs[1]);
            printf("%d
    ",ans);
        }
        return 0;
    }
    
  • 相关阅读:
    iOS录音后播放声音小,AudioSessionInitialize failed,AudioQueueStart failed (-50)
    NSAttributedString描述
    删除光标前的字符
    离线下载Xcode的文档
    20145209 实验五 《网络编程与安全》 实验报告
    20145209 实验四 《android开发基础》 实验报告
    20145209 实验三 《敏捷开发与XP实践》 实验报告
    20145209 实验二 《Java面向对象程序设计》 实验报告
    20145209 实验一《Java开发环境的熟悉》实验报告
    20145209 2016-2017-2 《Java程序设计》课堂实践内容
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/14632917.html
Copyright © 2011-2022 走看看