读完题后:哎线段树水题呀!
再一看数据范围:好像哪里不对劲。。。
其实这道题并不难,因为 m 值很小,所以可以用 O ( n 2 ) O(n^2) O(n2) 的算法直接过。
对于每个 1 操作,把它记下来。对于每个 2 操作,将之前所有记录的区间与 2 操作取个交集就 ok 了。当然也可以把 2 操作也记下来,对于下一个 2 操作,只需从上一个 2 处往后依次取交集就好。 这样能优化一点时间复杂度。
#include <stdio.h>
#include <iostream>
using namespace std;
struct node{
long long l,r,w;
}query[1005];
int main(void){
long long n,m,cnt=0;
cin >> n >> m;
for(int i=1;i<=m;i++){
long long flag,x,y,w,ans=0;
cin >> flag;
if(flag == 1){
cin >> x >> y >> w;
query[++cnt].l = x;
query[ cnt].r = y;
query[ cnt].w = w;
}
else{
cin >> x >> y;
for(int j=1;j<=cnt;j++){
if(query[j].l>y || query[j].r<x) continue; //取交集
ans += (min(query[j].r,y)-max(query[j].l,x)+1)*query[j].w;
}
cout << ans << endl;
}
}
return 0;
}