[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)
输入输出样例
说明
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:
%:pragma GCC optimize() #include<bits/stdc++.h> using namespace std; ; int n,k,las,cnt,ans,b[N]; char ch; struct line {int x,y;}a[N]; class node { private: int v,t; node *l,*r; public: #define m ((l)+(r)>>1) node() {l=r=,v=t=;} inline void pushup(node* cu) { cu->v=; ) cu->v+=cu->l->v; ) cu->v+=cu->r->v; } inline void pushdown(node *cu) { ) cu->l->t+=cu->t,cu->l->v+=cu->t; ) cu->r->t+=cu->t,cu->r->v+=cu->t; cu->t=; } inline void setup(node* &cu,int l,int r) { cu=new node; ==r) {cu->v=cu->t=; return;} setup(cu->l,l,m),setup(cu->r,m,r); pushup(cu); } inline void update(node* &cu,int l,int r,int aiml,int aimr) { if (l>=aiml&&r<=aimr) {cu->v++,cu->t++; return;} pushdown(cu); if (aimr<=m) update(cu->l,l,m,aiml,aimr); else if (aiml>=m) update(cu->r,m,r,aiml,aimr); else update(cu->l,l,m,aiml,aimr),update(cu->r,m,r,aiml,aimr); pushup(cu); } inline int answer(node* &cu,int l,int r,int x) { ==r) return cu->v; pushdown(cu); return x<m?answer(cu->l,l,m,x):answer(cu->r,m,r,x); } }t,*root; inline int read() { ,f=; ch=getchar(); :,ch=getchar(); +ch-',ch=getchar(); return x*f; } int main() { n=read(),k=read(),ans=las=,b[]=; ,x; i<=n; i++) { x=read(); while (ch!='L'&&ch!='R') ch=getchar(); if (ch=='L') a[i].x=las-x,a[i].y=las,b[i]=las-x,las=a[i].x; else a[i].x=las,a[i].y=las+x,b[i]=las+x,las=a[i].y; } sort(b,b++n); cnt=unique(b,b++n)-b; root=,t.setup(root,,cnt); ,l,r; i<=n; i++) { l=a[i].x,r=a[i].y; l=lower_bound(b,b+cnt,l)-b,l++; r=lower_bound(b,b+cnt,r)-b,r++; t.update(root,,cnt,l,r); } ,s; i<cnt; i++) s=t.answer(root,,cnt,i),ans+=(b[i]-b[i-])*(s>=k); cout<<ans<<endl; ; }