--- title: "粉刷栅栏" created: 2025-11-28 tags: - 算法 --- # 粉刷栅栏 ## 题目 [粉刷栅栏](https://www.acwing.com/problem/content/description/1989/) ![[image-311119dd.png]] ## 思路分析 和上一题基本一样 问题其实就是 粉刷过的话 就在这个区间++ 所以还是用差分 想办法把向左向右移动转变成l,r+1的形式 不过注意的是 我们的区间与上一题不同 这次是左闭右开 从0走到2 2可是没被刷的 所以2就是那个r+1 所以在离散化时直接加入这个找到的r就够了 不必加1 最后要注意的一点就是 因为我们处理的是离散化后的差分数组 真实的被粉刷的栅栏数是不能用++算出的 得使用res+=alls[i] - alls[i - 1] 用记录的下标相减 这才是真实的长度 ## 代码实现 ```cpp #include using namespace std; typedef long long LL; const int N=2e5; LL l[N],r[N],b[N]; vector alls; int n; int find(int x){ int l=0,r=alls.size()-1; while(l>1; if(alls[mid]>=x) r=mid; else l=mid+1; } return r; // return lower_bound(alls.begin(),alls.end(),x)-alls.begin(); } int main() { cin>>n; int idx=0,dis; char dir; for(int i=0;i>dis>>dir; //注意 区间为左闭右开 从0走到2处 2并没有被刷 所以r不需要放+1 if (dir == 'R'){ l[i]=idx; r[i]=idx+dis; idx+=dis; alls.push_back(l[i]); alls.push_back(r[i]); } else if(dir=='L'){ l[i]=idx-dis; r[i]=idx; idx-=dis; alls.push_back(l[i]); alls.push_back(r[i]); } } sort(alls.begin(),alls.end()); alls.erase(unique(alls.begin(),alls.end()),alls.end()); for(int i=0;i 1) { res += alls[i] - alls[i - 1];// 累加被多次覆盖的区间长度 } } cout<