• E1. Array and Segments (Easy version)(暴力) && E2. Array and Segments (Hard version)(线段树维护)


    题目链接:

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

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

    题目大意:

    给你n个数,然后给你m个区间,每一个区间代表将给定的n个数这个区间内都减去1,每个区间最多使用一次。然后问你使用哪些区间能够使得这n个数中最大数和最小的差值最大?

    首先对于E1:这么小的数据不暴力搞啥??直接问枚举就完事了,每一次枚举的时候保持一个数不变,假设当前的数是最大的,然后其他的只要是不包含这个数的区间,都减去,这样就能让最小的那个位置尽可能的小了。

    AC代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 # define ll long long
     4 # define inf 0x3f3f3f3f
     5 const int maxn = 400+100;
     6 int a[maxn],b[maxn],sto[maxn];
     7 struct node
     8 {
     9     int le;
    10     int ri;
    11 } q[maxn];
    12 int main()
    13 {
    14     int n,m;
    15     scanf("%d %d",&n,&m);
    16     for(int i=1; i<=n; i++)
    17     {
    18         scanf("%d",&a[i]);
    19     }
    20     for(int i=1; i<=m; i++)
    21     {
    22         scanf("%d %d",&q[i].le,&q[i].ri);
    23     }
    24     int maxx=-inf,id=0;
    25     for(int i=1; i<=n; i++)
    26     {
    27         int t1=-inf,t2=inf;
    28         for(int j=1; j<=n; j++)
    29         {
    30             b[j]=a[j];
    31         }
    32         for(int j=1; j<=m; j++)
    33         {
    34             if(i>=q[j].le&&i<=q[j].ri)
    35                 continue;
    36             for(int k=q[j].le; k<=q[j].ri; k++)
    37             {
    38                 b[k]-=1;
    39             }
    40         }
    41         for(int j=1; j<=n; j++)
    42         {
    43             t1=max(t1,b[j]);
    44             t2=min(t2,b[j]);
    45         }
    46         if(t1-t2>maxx)
    47         {
    48             maxx=t1-t2;
    49             id=i;
    50         }
    51     }
    52   //  cout<<m<<endl;
    53     printf("%d
    ",maxx);
    54     int num=0;
    55   //  cout<<1<<" "<<num<<endl;
    56     for(int i=1; i<=m; i++)
    57     {
    58         if(id>=q[i].le&&id<=q[i].ri)
    59             continue;
    60           //  cout<<1<<endl;
    61         sto[++num]=i;
    62     }
    63   //  cout<<2<<" "<<num<<endl;
    64     printf("%d
    ",num);
    65     for(int i=1; i<=num; i++)
    66     {
    67         if(i==1)
    68             printf("%d",sto[i]);
    69         else
    70             printf(" %d",sto[i]);
    71     }
    72     printf("
    ");
    73     return 0;
    74 }
    View Code

    其次对于E2:我们可以寻找最小的数的位置,这个时候为什么不和E1一样去找最大的数的位置呢?因为我们要利用区间的性质,对于每一个节点,我们需要从第一个位置开始。

    对于当枚举到第i个节点的时候,需要把包括i的区间都给整上,这个时候求一下最值之差,当枚举到第i+1个节点的时候,我们只需要把不包括第i个节点但是包括第i+1个节点的区间给整上就可以了,这样就能省去很多不必要的操作了。

    AC代码:

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 # define ll long long
      4 # define inf 0x3f3f3f3f
      5 # define lson l,m,rt<<1
      6 # define rson m+1,r,rt<<1|1
      7 const int maxn = 1e5+200;
      8 int minn[maxn<<2],maxx[maxn<<2],dif[maxn<<2];
      9 int lazy[maxn<<2];
     10 struct node
     11 {
     12     int le;
     13     int ri;
     14 } edge[500+10];
     15 int sto[maxn];
     16 int ans1,ans2;
     17 vector<int>q1[maxn],q2[maxn];
     18 void up(int rt)
     19 {
     20     minn[rt]=min(minn[rt<<1],minn[rt<<1|1]);
     21     maxx[rt]=max(maxx[rt<<1],maxx[rt<<1|1]);
     22     dif[rt]=maxx[rt]-minn[rt];// 本来查找最值得差的时候是直接询问到底部的,加了这个就不需要了,学到了!!
     23 }
     24 void build(int l,int r,int rt)
     25 {
     26     if(l==r)
     27     {
     28         int tmp;
     29         scanf("%d",&tmp);
     30         minn[rt]=tmp;
     31         maxx[rt]=tmp;
     32         return ;
     33     }
     34     int m=(l+r)>>1;
     35     build(lson);
     36     build(rson);
     37     up(rt);
     38 }
     39 void down(int rt)
     40 {
     41     if(lazy[rt])
     42     {
     43         lazy[rt<<1]+=lazy[rt];
     44         lazy[rt<<1|1]+=lazy[rt];
     45         minn[rt<<1]+=lazy[rt];
     46         minn[rt<<1|1]+=lazy[rt];
     47         maxx[rt<<1]+=lazy[rt];
     48         maxx[rt<<1|1]+=lazy[rt];
     49         lazy[rt]=0;
     50     }
     51 }
     52 void update(int l,int r,int rt,int L,int R,int p)
     53 {
     54     if(L<=l&&R>=r)
     55     {
     56         minn[rt]+=p;
     57         maxx[rt]+=p;
     58         lazy[rt]+=p;
     59         return ;
     60     }
     61     down(rt);
     62     int m=(l+r)>>1;
     63     if(L<=m)
     64         update(lson,L,R,p);
     65     if(R>m)
     66         update(rson,L,R,p);
     67     up(rt);
     68 }
     69 //int querymax(int l,int r,int rt)
     70 //{
     71 //    if(l==r)
     72 //    {
     73 //        return  maxx[rt];
     74 //    }
     75 //    int t1;
     76 //    down(rt);
     77 //    int m=(l+r)>>1;
     78 //    if(l<=m)querymax(lson);
     79 //    if(r>m)querymax(rson);
     80 //    up(rt);
     81 //}
     82 //void querymin(int l,int r,int rt)
     83 //{
     84 //    if(l==r)
     85 //    {
     86 //        ans2=min(ans2,minn[rt]);
     87 //        return ;
     88 //    }
     89 //    down(rt);
     90 //    int m=(l+r)>>1;
     91 //    querymin(lson);
     92 //   querymin(rson);
     93 //    up(rt);
     94 //}
     95 int main()
     96 {
     97     int n,m,tmp,len;
     98     scanf("%d %d",&n,&m);
     99     build(1,n,1);
    100     int ans=-inf,id=0;
    101     for(int i=1; i<=m; i++)
    102     {
    103         scanf("%d %d",&edge[i].le,&edge[i].ri);
    104         q1[edge[i].le].push_back(i);
    105         q2[edge[i].ri].push_back(i);
    106     }
    107     for(int i=1; i<=n; i++)
    108     {
    109         len=q2[i-1].size();
    110         for(int j=0; j<len; j++)
    111         {
    112             tmp=q2[i-1][j];
    113             update(1,n,1,edge[tmp].le,edge[tmp].ri,1);
    114         }
    115         len=q1[i].size();
    116         for(int j=0; j<len; j++)
    117         {
    118             tmp=q1[i][j];
    119             update(1,n,1,edge[tmp].le,edge[tmp].ri,-1);
    120         }
    121         if(ans<dif[1])
    122         {
    123             ans=dif[1];
    124             id=i;
    125         }
    126     }
    127     int num=0;
    128    printf("%d
    ",ans);
    129     for(int i=1; i<=m; i++)
    130     {
    131         if(edge[i].le<=id&&edge[i].ri>=id)
    132         {
    133             sto[++num]=i;
    134         }
    135     }
    136     printf("%d
    ",num);
    137     for(int i=1; i<=num; i++)
    138     {
    139         if(i==1)
    140             printf("%d",sto[i]);
    141         else
    142             printf(" %d",sto[i]);
    143     }
    144     printf("
    ");
    145     return 0;
    146 }
    View Code
  • 相关阅读:
    App架构师实践指南四之性能优化一
    App架构师实践指南三之基础组件
    App架构师实践指南二之App开发工具
    App架构师实践指南一之App基础语法
    Linux下阅读MHT文件
    What Is Docker & Docker Container ? A Deep Dive Into Docker !
    Difference between Docker Image and Container?
    RabbitMQ .NET/C# Client API Guide
    How RabbitMQ Works and RabbitMQ Core Concepts
    Message Queue vs Message Bus — what are the differences?
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10325140.html
Copyright © 2020-2023  润新知