[luogu P2205] [USACO13JAN]畫柵欄Painting the Fence
[luogu P2205] [USACO13JAN]畫柵欄Painting the Fence
題目描述
Farmer John has devised a brilliant method to paint the long fence next to his barn (think of the fence as a one-dimensional number line). He simply attaches a paint brush to his favorite cow Bessie, and then retires to drink a cold glass of water as Bessie walks back and forth across the fence, applying paint to any segment of the fence that she walks past.
Bessie starts at position 0 on the fence and follows a sequence of N moves (1 <= N <= 100,000). Example moves might be "10 L", meaning Bessie moves 10 units to the left, or "15 R", meaning Bessie moves 15 units to the right. Given a list of all of Bessie‘s moves, FJ would like to know what area of the fence gets painted with at least K coats of paint. Bessie will move at most 1,000,000,000 units away from the origin during her walk.
Farmer John 想出了一個給牛棚旁的長圍墻塗色的好方法。(為了簡單起見,我們把圍墻看做一維的數軸,每一個單位長度代表一塊柵欄)他只是簡單的把刷子蘸滿顏料,系在他最喜歡的奶牛Bessie上,然後讓Bessie來回地經過圍墻,自己則在一旁喝一杯冰鎮的涼水。(……-_-|||) Bessie 經過的所有圍墻都會被塗上一層顏料。Bessie從圍墻上的位置0出發,並將會進行N次移動(1 <= N <= 100,000)。比如說,“10 L”的意思就是Bessie向左移動了10個單位。再比如說“15 R”的意思就是Bessie向右移動了15個單位。給出一系列Bessie移動的清單。FJ 想知道有多少塊柵欄塗上了至少K層塗料。註意:Bessie最多會移動到離原點1,000,000,000單位遠的地方。
輸入輸出格式
輸入格式:
-
第1行: 兩個整數: N K
- 第2...N+1 行: 每一行都描述了Bessie的一次移動。 (比如說 “15 L")
輸出格式:
- 一個整數:被至少塗上K層塗料的柵欄數
(註意:輸出的最後一定要輸出換行符!否則會WA)
輸入輸出樣例
輸入樣例#1: 復制6 2
2 R
6 L
1 R
8 L
1 R
2 R
輸出樣例#1: 復制
6
說明
PS1:來源:usaco jan silver P01 想看原題的請戳http://www.usaco.org/index.php?page=viewproblem2&cpid=226)
PS2:測試數據也可以在在http://www.usaco.org/index.php?page=jan13problems上下載,還可以看到題解(不過是英文的:-D)
PS3:如果有翻譯的問題或題目的不理解,可以在問答後面留言的說。
這道題很早就寫過,當時用離散+差分就水過去了。
今天心血來潮寫了一顆鏈表指針版的線段樹。。
這真是個好東西。。
還有usaco竟然可以載數據,很妙啊。。
哦還有就是,今天終於會用unique,lower_bound和upper_bound了。
code:
1 %:pragma GCC optimize(2) 2 #include<bits/stdc++.h> 3 using namespace std; 4 const int N=100005; 5 int n,k,las,cnt,ans,b[N]; char ch; 6 struct line {int x,y;}a[N]; 7 class node { 8 private: 9 int v,t; node *l,*r; 10 public: 11 #define m ((l)+(r)>>1) 12 node() {l=r=0,v=t=0;} 13 inline void pushup(node* cu) { 14 cu->v=0; 15 if (cu->l!=0) cu->v+=cu->l->v; 16 if (cu->r!=0) cu->v+=cu->r->v; 17 } 18 inline void pushdown(node *cu) { 19 if (cu->l!=0) cu->l->t+=cu->t,cu->l->v+=cu->t; 20 if (cu->r!=0) cu->r->t+=cu->t,cu->r->v+=cu->t; 21 cu->t=0; 22 } 23 inline void setup(node* &cu,int l,int r) { 24 cu=new node; 25 if (l+1==r) {cu->v=cu->t=0; return;} 26 setup(cu->l,l,m),setup(cu->r,m,r); 27 pushup(cu); 28 } 29 inline void update(node* &cu,int l,int r,int aiml,int aimr) { 30 if (l>=aiml&&r<=aimr) {cu->v++,cu->t++; return;} 31 pushdown(cu); 32 if (aimr<=m) update(cu->l,l,m,aiml,aimr); else 33 if (aiml>=m) update(cu->r,m,r,aiml,aimr); 34 else update(cu->l,l,m,aiml,aimr),update(cu->r,m,r,aiml,aimr); 35 pushup(cu); 36 } 37 inline int answer(node* &cu,int l,int r,int x) { 38 if (l+1==r) return cu->v; 39 pushdown(cu); 40 return x<m?answer(cu->l,l,m,x):answer(cu->r,m,r,x); 41 } 42 }t,*root; 43 inline int read() { 44 int x=0,f=1; ch=getchar(); 45 while (ch<‘0‘||ch>‘9‘) f=(ch==‘-‘)?-1:1,ch=getchar(); 46 while (ch>=‘0‘&&ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar(); 47 return x*f; 48 } 49 int main() { 50 n=read(),k=read(),ans=las=0,b[0]=0; 51 for (int i=1,x; i<=n; i++) { 52 x=read(); 53 while (ch!=‘L‘&&ch!=‘R‘) ch=getchar(); 54 if (ch==‘L‘) a[i].x=las-x,a[i].y=las,b[i]=las-x,las=a[i].x; 55 else a[i].x=las,a[i].y=las+x,b[i]=las+x,las=a[i].y; 56 } 57 sort(b,b+1+n); 58 cnt=unique(b,b+1+n)-b; 59 root=0,t.setup(root,1,cnt); 60 for (int i=1,l,r; i<=n; i++) { 61 l=a[i].x,r=a[i].y; 62 l=lower_bound(b,b+cnt,l)-b,l++; 63 r=lower_bound(b,b+cnt,r)-b,r++; 64 t.update(root,1,cnt,l,r); 65 } 66 for (int i=1,s; i<cnt; i++) 67 s=t.answer(root,1,cnt,i),ans+=(b[i]-b[i-1])*(s>=k); 68 cout<<ans<<endl; 69 return 0; 70 }View Code
[luogu P2205] [USACO13JAN]畫柵欄Painting the Fence