1. 程式人生 > >【掃描線或樹狀數組】CSU 1335 高橋和低橋

【掃描線或樹狀數組】CSU 1335 高橋和低橋

等於 case spa .cn print splay def 分享 a20

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\n",++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\n",++cas,ans);
71     }
72     return 0;
73 }
樹狀數組區間修改單點查詢

【掃描線或樹狀數組】CSU 1335 高橋和低橋