【掃描線或樹狀數組】CSU 1335 高橋和低橋
阿新 • • 發佈:2017-08-26
等於 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 高橋和低橋