洛谷P2205 [USACO13JAN]画栅栏Painting the Fence
Posted third2333
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷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 }
以上是关于洛谷P2205 [USACO13JAN]画栅栏Painting the Fence的主要内容,如果未能解决你的问题,请参考以下文章
洛谷 P2205 [USACO13JAN]画栅栏Painting the Fence
[luogu P2205] [USACO13JAN]画栅栏Painting the Fence
洛谷P3070 [USACO13JAN]岛游记Island Travels