• 【扫描线或树状数组】CSU 1335 高桥和低桥


    http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1335

    【题意】

    • 给定n座桥的高度,给定m次洪水每次的涨水水位ai和退水水位bi
    • 询问有多少座桥被淹的次数大于等于k
    • 洪水最开始的水位为1

    【思路】

    • 每座桥被淹一次是这样的:开始时的水位小于桥的高度,洪水最高点的水位不小于桥的高度,如有一座高度为5的桥,对于数据7 6和7 3被淹的次数都是1(看5在不在(1,7]的区间内)
    • 把n座桥排序,每次洪水都有一个区间的桥被淹,问最后每座桥被淹多少次
    • 这就是裸的扫描线,或者树状数组区间修改单点查询也可以

    【AC】

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<string>
     5 #include<cstring> 
     6 using namespace std;
     7 typedef long long ll;
     8 
     9 const int maxn=1e5+2;
    10 int a[maxn];
    11 int n,m,k;
    12 int f[maxn];
    13 void init()
    14 {
    15     memset(f,0,sizeof(f));
    16 }
    17 int main()
    18 {
    19     int cas=0;
    20     while(~scanf("%d%d%d",&n,&m,&k))
    21     {
    22         init();
    23         for(int i=1;i<=n;i++)
    24         {
    25             scanf("%d",&a[i]);
    26         }
    27         sort(a+1,a+n+1);
    28         int x,y;
    29         int st=1,ed;
    30         for(int i=1;i<=m;i++)
    31         {
    32             scanf("%d%d",&x,&y);
    33             ed=x;
    34             int pos1=upper_bound(a+1,a+1+n,st)-a;
    35             int pos2=upper_bound(a+1,a+1+n,ed)-a-1;
    36             f[pos1]++;
    37             f[pos2+1]--;
    38             st=y;
    39         }
    40         int ans=0;
    41         int s=0;
    42         for(int i=1;i<=n;i++)
    43         {
    44             s+=f[i];
    45             if(s>=k) ans++;
    46         }
    47         printf("Case %d: %d
    ",++cas,ans);
    48     }
    49     return 0;
    50 }
    扫描线
     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<string>
     5 #include<cstring> 
     6 using namespace std;
     7 typedef long long ll;
     8 
     9 const int maxn=1e5+2;
    10 int a[maxn];
    11 int tree[maxn];
    12 int n,m,k;
    13 int lowbit(int x)
    14 {
    15     return x&(-x);
    16 }
    17 void add(int k,int x)
    18 {
    19     while(k<=n)
    20     {
    21         tree[k]+=x;
    22         k+=lowbit(k);
    23     }
    24 }
    25 int query(int k)
    26 {
    27     int res=0;
    28     while(k)
    29     {
    30         res+=tree[k];
    31         k-=lowbit(k);
    32     }
    33     return res;
    34 }
    35 void init()
    36 {
    37     memset(tree,0,sizeof(tree));
    38 }
    39 int main()
    40 {
    41     int cas=0;
    42     while(~scanf("%d%d%d",&n,&m,&k))
    43     {
    44         init();
    45         for(int i=1;i<=n;i++)
    46         {
    47             scanf("%d",&a[i]);
    48         }
    49         sort(a+1,a+n+1);
    50         int x,y;
    51         int st=1,ed;
    52         for(int i=1;i<=m;i++)
    53         {
    54             scanf("%d%d",&x,&y);
    55             ed=x;
    56             int pos1=upper_bound(a+1,a+1+n,st)-a;
    57             int pos2=upper_bound(a+1,a+1+n,ed)-a-1;
    58             add(pos1,1);
    59             add(pos2+1,-1);
    60             st=y;
    61         }
    62         int ans=0;
    63         for(int i=1;i<=n;i++)
    64         {
    65             if(query(i)>=k)
    66             {
    67                 ans++;
    68             }
    69         }
    70         printf("Case %d: %d
    ",++cas,ans);
    71     }
    72     return 0;
    73 }
    树状数组区间修改单点查询
  • 相关阅读:
    学习进度16
    个人总结
    人月神话阅读笔记09
    人月神话阅读笔记08
    人月神话阅读笔记07
    构建之法阅读笔记06
    构建之法阅读笔记05
    构建之法阅读笔记04
    构建之阅读笔记03
    Python安装 pip 和 easy_install
  • 原文地址:https://www.cnblogs.com/itcsl/p/7435434.html
Copyright © 2020-2023  润新知