1. 程式人生 > >[luogu P2205] [USACO13JAN]畫柵欄Painting the Fence

[luogu P2205] [USACO13JAN]畫柵欄Painting the Fence

radi update usaco node nod hide pri click get

[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