如题,已知一个数列,你需要进行下面两种操作:
k
。给你一个数列和一个操作队列,请输出数列经过这些操作队列中所有操作后的结果。
1 <= n,m <= 10^5
数列中所有元素之和 <= 10^18
第一行包含两个整数 n,m
,分别表示该数列数字的个数和操作的总个数。
第二行包含 n
个用空格分隔的整数,其中第 i
个数字表示数列第 i
项的初始值。
接下来 m
行每行包含 3 或 4 个整数,表示一个操作,具体如下:
1 x y k
:将区间 [x,y]
内每个数加上 k
。2 x y
:输出区间 [x,y]
内每个数的和。输出包含若干行整数,即为所有操作 2 的结果。
5 5
1 5 4 2 3
2 2 4
1 2 3 2
2 3 4
1 1 5 1
2 1 4
11
8
20
#include
using namespace std;
const int maxn=100010;
int a[maxn+2];
struct tree{
int l,r;
long long pre,add;
}t[4*maxn+2];
void bulid(int p,int l,int r){
t[p].l=l;t[p].r=r;
if(l==r){
t[p].pre=a[l];
return;
}
int mid=l+r>>1;
bulid(p*2,l,mid);
bulid(p*2+1,mid+1,r);
t[p].pre=t[p*2].pre+t[p*2+1].pre;
}
void spread(int p){
if(t[p].add){
t[p*2].pre+=t[p].add*(t[p*2].r-t[p*2].l+1);
t[p*2+1].pre+=t[p].add*(t[p*2+1].r-t[p*2+1].l+1);
t[p*2].add+=t[p].add;
t[p*2+1].add+=t[p].add;
t[p].add=0;
}
}
void change(int p,int x,int y,int z){
if(x<=t[p].l && y>=t[p].r){
t[p].pre+=(long long)z*(t[p].r-t[p].l+1);
t[p].add+=z;
return;
}
spread(p);
int mid=t[p].l+t[p].r>>1;
if(x<=mid) change(p*2,x,y,z);
if(y>mid) change(p*2+1,x,y,z);
t[p].pre=t[p*2].pre+t[p*2+1].pre;
}
long long ask(int p,int x,int y){
if(x<=t[p].l && y>=t[p].r) return t[p].pre;
spread(p);
int mid=t[p].l+t[p].r>>1;
long long ans=0;
if(x<=mid) ans+=ask(p*2,x,y);
if(y>mid) ans+=ask(p*2+1,x,y);
return ans;
}
int main(){
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>a[i];
bulid(1,1,n);
for(int i=1;i<=m;i++)
{
int q,x,y,z;
cin>>q;
if(q==1){
cin>>x>>y>>z;
change(1,x,y,z);
}
else {
cin>>x>>y;
cout<
给你一个待安排日程表calendar
,逐个将日程添加到你的日程安排表中。如果要添加的日程安排不会造成重复预订,则可以存储这个新的日程安排。如果一个日程可以被添加到你的日程安排表中,输出true
;否则输出false
当两个日程安排有一些时间上的交叉时(例如两个日程安排都在同一时间内),就会产生 重复预订 。
日程可以用一对整数 start
和 end
表示,这里的时间是半开区间,即 [start, end)
, 实数 x
的范围为, start <= x < end
。
0 <= start < end <= 10^9
0 < calendar.length <= 10^9
第一行输入一个整数表示 calendar.length
随后calendar.length
行,每行两个数分别表示 start_i、end_i
输出 calendar.length
行,第i
行表示第i
个日程是否可以被添加到你的日程安排表中
3
10 20
15 25
20 30
true
false
true
#include
#include
using namespace std;
unordered_map tree, lazy;
bool query(int start, int end, int l, int r, int idx) {
if (r < start || end < l) {
return false;
}
// 如果该区间已被预订,则直接返回
if (lazy.count(idx)) {
return true;
}
if (start <= l && r <= end) {
return tree.count(idx);
}
int mid = (l + r) >> 1;
return query(start, end, l, mid, 2 * idx) ||
query(start, end, mid + 1, r, 2 * idx + 1);
}
void update(int start, int end, int l, int r, int idx) {
if (r < start || end < l) {
return;
}
if (start <= l && r <= end) {
tree[idx]=true;
lazy[idx]=true;
} else {
int mid = (l + r) >> 1;
update(start, end, l, mid, 2 * idx);
update(start, end, mid + 1, r, 2 * idx + 1);
tree[idx]=true;
if (lazy.count(2 * idx) && lazy.count(2 * idx + 1)) {
lazy[idx]=true;
}
}
}
bool book(int start, int end) {
if (query(start, end - 1, 0, 1e9, 1)) {
return false;
}
update(start, end - 1, 0, 1e9, 1);
return true;
}
int main(){
int n, start, end;
cin>>n;
for(int i=0;i>start>>end;
if(book(start, end)){
cout<<"true"<