[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

 

转载于:https://www.cnblogs.com/whc200305/p/7746193.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值