由于坐标太长了,开数组这样的操作是肯定行不通的,离散化的原理就是将没有操作的地方全部抹去,然后再将抹去后的序列求前缀和,即可O(1)时间查询我们需要的区间信息,话不多说,直接上代码吧:
#includeusing namespace std; #define int long long #define PII pair #define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); int n,m,x,c,l,r; set Point; //存储所有要用到的点,set用来去重 vector AllPoint; //存储所有要用到的点 vector add; //存储要进行累加的操作,first表示位置,second表示加的值 vector Find; //存储查询的区间,first表示区间l值,second表示区间r值 int a[300005]; //存储最终的离散化操作后的数组 signed main(){ IOS cin>>n>>m; for(int i = 1;i <= n;++i) cin>>x>>c,Point.insert(x),add.push_back(PII(x,c)); for(int i = 1;i <= n;++i) cin>>l>>r,Point.insert(l),Point.insert(r),Find.push_back(PII(l,r)); for(auto it : Point) AllPoint.push_back(it); //把去重后的点放在AllPoint中 for(int i = 0,j = add.size();i < j;++i){ int f = add[i].first,mid; l = 0,r = AllPoint.size() - 1; while(l <= r){ mid = l + r >> 1; if(AllPoint[mid] < f) l = mid + 1; else if(AllPoint[mid] > f) r = mid - 1; else break; } a[mid] += add[i].second; } for(int i = 1,j = AllPoint.size();i < j;++i) a[i] += a[i - 1]; //以上是求前缀和 for(int i = 0;i < m;++i){ int f = Find[i].first,t = Find[i].second,mid; l = 0,r = AllPoint.size() - 1; while(l <= r){ mid = l + r >> 1; if(AllPoint[mid] > f) r = mid - 1; else if(AllPoint[mid] < f) l = mid + 1; else break; } f = mid; l = 0,r = AllPoint.size() - 1; while(l <= r){ mid = l + r >> 1; if(AllPoint[mid] > t) r = mid - 1; else if(AllPoint[mid] < t) l = mid + 1; else break; } t = mid; if(f == 0) cout<



