zoukankan      html  css  js  c++  java
  • codeforces#1108E2. Array and Segments (线段树+扫描线)

    题目链接:

    http://codeforces.com/contest/1108/problem/E2

    题意:

    给出$n$个数和$m$个操作

    每个操作是下标为$l$到$r$的数减一

    选出某些操作,使$n$个数的最大值减最小值最大

    数据范围:

    $1 le n le 10^5$

    $0 le m le 300$

    $-10^6 le a_i le 10^6$

    分析: 

    假设选择第$i$位置作为最小值,那么我们选取所有包含$i$的区间可以得到选择第$i$位置为最小值的最佳答案

    第一步,我们从$1$到$n$枚举最小值的位置

    第二步,我们用扫描线来添加和减少题目给出的区间影响,例如最小值为$i$时,我们要让所有的包含i区间的操作生效

    第三步,计算以$i$为最小值时的最优解

    ac代码:

    #include<bits/stdc++.h>
    #define ll long long
    #define pa pair<int,int>
    using namespace std;
    const int maxn=1e5+10;
    const int maxm=300+10;
    const ll mod=1e9+7;
    int ans=-1,inde,tree[maxn*4],lazy[maxn*4],num[maxn],n;
    pa quer[maxm];
    vector<pa>ve[maxn];
    vector<int>ve2;
    void build(int st,int en,int rt)
    {
        if(st==en)
        {
            tree[rt]=num[st];
            return ;
        }
        int md=(st+en)/2;
        build(st,md,rt*2);
        build(md+1,en,rt*2+1);
        tree[rt]=max(tree[rt*2],tree[rt*2+1]);
    }
    void update(int l,int r,int x,int st,int en,int rt)
    {
        if(l>en||r<st)return ;
        if(l<=st&&r>=en)
        {
            lazy[rt]+=x;
            tree[rt]+=x;
            return ;
        }
        if(lazy[rt])
        {
            int v=lazy[rt];
            lazy[rt*2]+=v;
            lazy[rt*2+1]+=v;
            tree[rt*2]+=v;
            tree[rt*2+1]+=v;
            lazy[rt]=0;
        }
        int md=(st+en)/2;
        update(l,r,x,st,md,rt*2);
        update(l,r,x,md+1,en,rt*2+1);
        tree[rt]=max(tree[rt*2],tree[rt*2+1]);
    }
    int Quer(int x,int st,int en,int rt)
    {
        if(st==en)
            return tree[rt];
        if(lazy[rt])
        {
            int v=lazy[rt];
            lazy[rt*2]+=v;
            lazy[rt*2+1]+=v;
            tree[rt*2]+=v;
            tree[rt*2+1]+=v;
            lazy[rt]=0;
        }
        int md=(st+en)/2;
        int res;
        if(x<=md)res=Quer(x,st,md,rt*2);
        else res=Quer(x,md+1,en,rt*2+1);
        tree[rt]=max(tree[rt*2],tree[rt*2+1]);
        return res;
    }
    int main()
    {
        int q;
        scanf("%d %d",&n,&q);
        for(int i=1;i<=n;i++)
            scanf("%d",&num[i]);
        build(1,n,1);
        for(int i=1;i<=q;i++)
        {
            int l,r;
            scanf("%d %d",&l,&r);
            quer[i].first=l;
            quer[i].second=r;
            ve[l].push_back(make_pair(i,-1));
            ve[r+1].push_back(make_pair(i,+1));
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=0;j<ve[i].size();j++)
            {
                int v=ve[i][j].first;
                int add=ve[i][j].second;
                update(quer[v].first,quer[v].second,add,1,n,1);
            }
            int res=tree[1]-Quer(i,1,n,1);
            if(res>ans)
            {
                inde=i;
                ans=res;
            }
        }
        printf("%d
    ",ans);
        int res=0;
        for(int i=1;i<=q;i++)
            if(inde>=quer[i].first&&inde<=quer[i].second)
                ve2.push_back(i);
        printf("%d
    ",ve2.size());
        for(int i=0;i<ve2.size();i++)
            printf("%d%c",ve2[i]," 
    "[i==ve2.size()-1]);
        return 0;
    }
    

      

  • 相关阅读:
    js加密解密 base64
    Server2003上部署Excel服务器
    SQL 2000和SQL 2005服务端口查看或修改
    IIS6.0的安装
    VSS 2005 配置(含录像)
    SQL2005开启远程连接功能
    SQL 2005 SP3在小内存计算机中安装(最佳方案)
    windows防火墙的使用
    Server2003上部署Excel服务器
    通过连接实例解读TCP/IP协议
  • 原文地址:https://www.cnblogs.com/carcar/p/11172560.html
Copyright © 2011-2022 走看看