差分数组前缀和优化,降低时间复杂度
码蹄集OJ-激光控制器
#include<bits/stdc++.h>
using namespace std;
int main( )
{int N;cin>>N;map<long,long>diff;long long pos=0;while(N--){int x;char c;cin>>x>>c;int l,r;if(c=='R'){l=pos;r=pos+x-1;pos=r;}if(c=='L'){l=pos-x+1;r=pos;pos=l;}diff[l]++;diff[r+1]--;}long long result=0;long long cur=0;long long le=LLONG_MIN;for(auto[co,d]:diff){if(le!=LLONG_MIN){ long long len=co-le;if(cur%4==1){result+=len;}}cur+=d;le=co;}cout<<result<<endl;return 0;
}
在一段范围内变化的题,可以采用暴力方法解决,但结果会超时。可以使用差分数组进行统计,最后统计结果。
定义一个diff差分数组,对于一段范围的左右边界,对左边界的差分数组加一,表示这个位置及后面的位置的值都加一,对右边界加一的差分数组减一,表示这个位置后的值都减一。这种办法和依次给每一个数组元素赋值是一样的,但这种方法节省了时间。
定义pos存储当前位置,初始时在原点。根据每一次操作找到左右边界,按上述方法存入差分数组中。
差分数组的统计:由于这道题的数据量大,采用map统计边界值,节省时间,而且map会从小到大排序。遍历这个差分数组,map中的数代表边界点,要从左向右整理每一个边界。每一个范围的变化数是相同的,所以统计这个范围的长度,如果符合题意,结果就是累加这个范围长度。
注意:要想知道每一个点变化了多少,就是累加map中的值的数,由于范围内的值等于零,所以范围内的变化数是相同的。