洛谷P2205 [USACO13JAN]画栅栏Painting the Fence

 

洛谷P2205 [USACO13JAN]画栅栏Painting the Fence
这是我的做法,我用了离散化+二分,比较慢

 1 #include <bits/stdc++.h> 
 2 #define For(i,j,k) for(int i=j;i<=k;i++) 
 3 #define int long long 
 4 #define LL long long 
 5 using namespace std ; 
 6 
 7 const int N = 100011 ; 
 8 struct node{
 9     int l,r,del ; 
10 }cnt[N*2];
11 int n,x1,x2,v,dir,num,t,K,tot ; 
12 LL sum ; 
13 int L[N],R[N],tmp[2*N],point[2*N] ; 
14 char s[4] ; 
15 
16 inline int read() 
17 {
18     int x = 0 , f = 1 ; 
19     char ch = getchar() ; 
20     while(ch<'0'||ch>'9') { if(ch=='-') f = -1 ; ch = getchar() ; } 
21     while(ch>='0'&&ch<='9') { x = x * 10+ch-48 ; ch = getchar() ; } 
22     return x * f ;  
23 }
24 
25 inline int erfen(int x)   // 在 point 数组中找 x 
26 {
27     int l = 1,r = t ; 
28     while(l<r) {
29         int mid=(l+r)/2 ; 
30         if(point[mid]>=x) 
31             r=mid ; 
32         else 
33             l=mid+1 ;         
34     }
35     return r ; 
36 }
37 
38 signed main() 
39 {
40     n = read() ; K = read() ; 
41     x1 = 0 ; x2 = 0 ; 
42     For(i,1,n) {
43         v = read() ; 
44         scanf("%s",s+1) ; 
45         if(s[1]=='L') x2-=v ; 
46         else x2+=v; 
47         L[i]=x1 ; R[i]=x2 ; 
48         x1=x2 ; 
49     } 
50     For(i,1,n) if(L[i]>R[i]) swap(L[i],R[i]) ; 
51     For(i,1,n) tmp[++tot]=L[i],tmp[++tot]=R[i] ; 
52     sort(tmp+1,tmp+tot+1) ; 
53     
54     point[++t] = tmp[1] ; 
55     For(i,2,tot) 
56         if(tmp[i]!=tmp[i-1]) point[++t] = tmp[i] ; 
57     For(i,1,t-1) {
58         cnt[i].l = point[i] ;  
59         cnt[i].r = point[i+1] ; 
60         cnt[i].del = 0 ; 
61     }
62     
63     For(i,1,n) {
64         int l = erfen(L[i]) ; 
65         cnt[l].del++ ; 
66         int r = erfen(R[i])-1 ;    
67         cnt[r+1].del-- ; 
68     }
69     For(i,1,t-1) {
70         num+=cnt[i].del ; 
71         if(num>=K) sum+=cnt[i].r-cnt[i].l ; 
72     }
73     printf("%lld\n",sum) ; 
74     return 0 ; 
75 }

 

 

其实差分就行了,不用二分
虽然时间复杂度也是 nlogn
但是因为不用而二分了,所以快了不少
大概快了300ms
另外也可以用map直接水

 

 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<cstring>
 6 int i,j,k,m,n,x,y,wz;
 7 struct ppp{
 8     int wz,lr;
 9 }a[200001];
10 bool cmp(ppp x,ppp y)
11 {
12     return x.wz<y.wz;
13 }
14 char c;
15 using namespace std;
16 int main()
17 {
18     scanf("%d %d",&n,&m);
19     for(i=1;i<=n;i++)
20     {
21         scanf("%d %c",&x,&c);
22         a[i*2-1].wz=wz;
23         if(c=='R')wz+=x;else wz-=x;
24         a[i*2].wz=wz;
25         if(a[i*2-1].wz<a[i*2].wz)
26         a[i*2-1].lr=0,a[i*2].lr=1;
27         else 
28         a[i*2-1].lr=1,a[i*2].lr=0;
29     }//存端点信息而不是线段信息
30 
31     sort(a+1,a+2*n+1,cmp);
32     int ans=0;
33     for(i=1;i<=n*2;i++)
34     {
35         if(k>=m)ans+=(a[i].wz-a[i-1].wz);
36         if(a[i].lr==0)k++;else k--;
37     }
38     cout<<ans;
39     return 0;
40 }

 

posted @ 2017-10-13 07:58  third2333  阅读(207)  评论(0编辑  收藏  举报