• hud -5124-lines(线段树)


    题目的意思是求重合层数最多的段(把点也看成段)。

    给的数据范围为N<1e5;

    ai<1e9;

    有于N只有1e5;那么离散化一下可以将ai的范围映射到1e5,而不改变原端点的相对大小。

    接下来用线段树来做就行了,要用lazy操作,到最后再把所有的值放下,然后比较每个点的大小,最大的就为重合最多的。

    线段树复杂度为N*log(N);

     1 #include<stdio.h>
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<string.h>
     5 #include<stdlib.h>
     6 #include<math.h>
     7 #include<map>
     8 void local(int l,int r,int k);
     9 void add(int l,int r,int k,int uu,int ww);
    10 typedef long long ll;
    11 typedef struct pp
    12 {
    13     int x;
    14     int y;
    15 } ss;
    16 int tree[4*100005];//线段树数组
    17 int su[100005*2];
    18 ss dd[100005];//结构体存段
    19 int N;
    20 using namespace std;
    21 int main(void)
    22 {
    23     int i,j,k,num;
    24     scanf("%d",&k);
    25     while(k--)
    26     {
    27         N=0;
    28         fill(tree, tree+4*100005,0);
    29         scanf("%d",&num);
    30         int z=0;
    31         map<int,int>my;//映射
    32         for(i=0; i<num; i++)
    33         {
    34             scanf("%d %d",&dd[i].x,&dd[i].y);
    35             su[z]=dd[i].x;
    36             z++;
    37             su[z]=dd[i].y;
    38             z++;
    39         }
    40         sort(su,su+z);
    41         j=1;
    42         for(i=0; i<z; i++)
    43         {
    44             if(my[su[i]]==0)
    45             {
    46                 my[su[i]]=j;
    47                 j++;
    48             }
    49 
    50         }//离散化
    51         for(i=0; i<num; i++)
    52         {
    53             int x=dd[i].x=my[dd[i].x];
    54             int y=dd[i].y=my[dd[i].y];
    55             add(x,y,0,1,j-1);//线段树加段更新
    56         }
    57         local(1,j-1,0);//最后下放查询
    58         printf("%d
    ",N);
    59     }
    60     return 0;
    61 
    62 }
    63 void add(int l,int r,int k,int uu,int ww)//建树更新
    64 {
    65     if(l>ww||r<uu)
    66     {
    67         return ;
    68     }
    69     else if(l<=uu&&r>=ww)
    70     {
    71         tree[k]+=1;
    72     }
    73     else
    74     {
    75         add(l,r,2*k+1,uu,(uu+ww)/2);
    76         add(l,r,2*k+2,(uu+ww)/2+1,ww);
    77     }
    78 }
    79 void local(int l,int r,int k)//下放查询
    80 {
    81     if(l==r)
    82     {
    83         if(N<tree[k])
    84         {
    85             N=tree[k];
    86         }
    87         return ;
    88     }
    89     else
    90     {
    91         tree[2*k+1]+=tree[k];
    92         tree[2*k+2]+=tree[k];
    93         local(l,(l+r)/2,2*k+1);
    94         local((l+r)/2+1,r,2*k+2);
    95 
    96     }
    97 }

    [title]1002 lines[/title] 我们可以将一条线段[x_i,y_i][xi​​,yi​​]分为两个端点x_ixi​​和(yi)+1(yi)+1,在x_ixi​​时该点会新加入一条线段,同样的,在(y_i)+1(yi​​)+1时该点会减少一条线段,因此对于2n个端点进行排序,

    x_ixi​​为价值1,y_iyi​​为价值-1,问题转化成了最大区间和,因为1一定在-1之前,因此问题变成最大前缀和,我们寻找最大值就是答案

     1 #include<stdio.h>
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<stdlib.h>
     5 #include<string.h>
     6 #include<math.h>
     7 #include<map>
     8 int f(const void*p,const void*q);
     9 typedef long long ll;
    10 typedef struct pp
    11 {
    12     int x;
    13     int y;
    14 } ss;
    15 using namespace std;
    16 ss a[100005*2];
    17 int main(void)
    18 {
    19     int i,j,k,p,q,s,l;
    20     scanf("%d",&k);
    21     while(k--)
    22     {
    23         scanf("%d",&p);
    24         int uu=0;
    25         for(i=0; i<p; i++)
    26         {
    27             scanf("%d",&s);
    28             a[uu].x=s;
    29             a[uu].y=1;
    30             uu++;
    31             scanf("%d",&l);
    32             a[uu].x=l;
    33             a[uu].y=0;
    34             uu++;
    35         }
    36         qsort(a,uu,sizeof(ss),f);
    37         ll sum=0;
    38         ll dd=0;
    39         for(i=0; i<uu; i++)
    40         {
    41             if(a[i].y==1)
    42             {
    43                 sum++;
    44                 if(sum>dd)
    45                 {
    46                     dd=sum;
    47                 }
    48             }
    49             else sum--;
    50         }
    51         printf("%lld
    ",dd);
    52 
    53     }
    54     return 0;
    55 }
    56 int f(const void*p,const void*q)
    57 {
    58     ss*w=(ss*)p;
    59     ss*r=(ss*)q;
    60     if(w->x==r->x)
    61     {
    62         return r->y-w->y;
    63     }
    64     return w->x-r->x;
    65 }
    View Code

     下面map映射改为二分查找

      1 #include<stdio.h>
      2 #include<algorithm>
      3 #include<iostream>
      4 #include<string.h>
      5 #include<stdlib.h>
      6 #include<math.h>
      7 #include<map>
      8 void local(int l,int r,int k);
      9 int er(int n,int m,int k);
     10 void add(int l,int r,int k,int uu,int ww);
     11 typedef long long ll;
     12 typedef struct pp
     13 {
     14     int x;
     15     int y;
     16 } ss;
     17 int tree[4*100005];
     18 int su[100005*2];
     19 int mapp[100005*2];
     20 ss dd[100005];
     21 int N=0;
     22 using namespace std;
     23 int main(void)
     24 {
     25     int i,j,k,p,q,num;
     26     scanf("%d",&k);
     27     while(k--)
     28     {
     29         N=0;
     30         fill(tree, tree+4*100005,0);
     31         scanf("%d",&num);
     32         int z=0;
     33         map<int,int>my;
     34         for(i=0; i<num; i++)
     35         {
     36             scanf("%d %d",&dd[i].x,&dd[i].y);
     37             su[z]=dd[i].x;
     38             z++;
     39             su[z]=dd[i].y;
     40             z++;
     41         }
     42         sort(su,su+z);
     43         j=1;
     44         mapp[0]=1;
     45         for(i=1; i<z; i++)
     46         {
     47             if(su[i]!=su[i-1])
     48             {
     49                 j++;
     50                 mapp[i]=j;
     51             }
     52             else mapp[i]=j;
     53 
     54         }
     55         for(i=0; i<num; i++)
     56         {
     57             int x=dd[i].x=er(0,z-1,dd[i].x);
     58             int y=dd[i].y=er(0,z-1,dd[i].y);
     59             add(x,y,0,1,j);
     60         }
     61         local(1,j,0);
     62         printf("%d
    ",N);
     63     }
     64     return 0;
     65 
     66 }
     67 
     68 
     69 void add(int l,int r,int k,int uu,int ww)
     70 {
     71     if(l>ww||r<uu)
     72     {
     73         return ;
     74     }
     75     else if(l<=uu&&r>=ww)
     76     {
     77         tree[k]+=1;
     78     }
     79     else
     80     {
     81         add(l,r,2*k+1,uu,(uu+ww)/2);
     82         add(l,r,2*k+2,(uu+ww)/2+1,ww);
     83     }
     84 }
     85 void local(int l,int r,int k)
     86 {
     87     if(l==r)
     88     {
     89         if(N<tree[k])
     90         {
     91             N=tree[k];
     92         }
     93         return ;
     94     }
     95     else
     96     {
     97         tree[2*k+1]+=tree[k];
     98         tree[2*k+2]+=tree[k];
     99         local(l,(l+r)/2,2*k+1);
    100         local((l+r)/2+1,r,2*k+2);
    101 
    102     }
    103 }
    104 int er(int n,int m,int k)
    105 {
    106     int zz=(n+m)/2;
    107     if(m<n)
    108     {
    109         return -1;
    110     }
    111     if(su[zz]==k)
    112     {
    113         return mapp[zz];
    114     }
    115     else if(su[zz]>k)
    116     {
    117         return er(n,zz-1,k);
    118     }
    119     else return er(zz+1,m,k);
    120 }
    View Code
    油!油!you@
  • 相关阅读:
    ffmpeg视频操作记录
    frida定义线程写图片文件
    frida创建静态域
    frida创建字符串
    pyppeteer_stealth
    python ast
    最小的js编译器
    excel加双引号和逗号
    JUnit 单元测试方法中启用子线程的问题
    ctrip 开源 DAL 框架相关问题总结
  • 原文地址:https://www.cnblogs.com/zzuli2sjy/p/4947038.html
Copyright © 2020-2023  润新知