链接
一道经典的线段树的题 , 注意下 query 的处理就好了 , 用到了 lazy , 算是自己复习了一遍线段树。
#include <bits/stdc++.h>
#define sc scanf
#define pr printf
const int N = 100010;
using namespace std;
long long tree[N<<2],lazy[N<<2];
void printf_tree(int root , int l , int r);
void Lazy(int root);
void Create_tree(int root , int l , int r);
void update(int root , int l , int r , int lh , int rh , long long value);
long long query(int root , int l , int r , int lh , int rh , long long value);
int main(int argc, char *argv[])
{
int t , n , q , i , j;
int opt , l , r;
long long value;
sc("%d",&t);
while (t--)
{
sc("%d %d",&n , &q);
memset(tree,0,sizeof(tree));
memset(lazy,0,sizeof(lazy));
Create_tree(1,1,n);
while(q--)
{
sc("%d %d %d %lld",&opt , &l , &r , &value);
if(opt == 1)
{
long long ans = query(1,1,n,l,r,value);
pr("%lld\n",ans);
}
else
{
update(1,1,n,l,r,value);
// query(1,1,n,l,r,value);
}
// printf_tree(1,1,n);
//pr("\n\n");
}
}
return 0;
}
void Create_tree(int root , int l , int r)
{
if(l == r)
{
sc("%lld",&tree[root]); return ;
}
int mid = (l+r)>>1;
Create_tree(root*2,l,mid);
Create_tree(root*2+1,mid+1,r);
tree[root] = max(tree[root*2] , tree[root*2+1]);
return ;
}
void update(int root , int l , int r , int lh , int rh , long long value)
{
//pr("%d %d %d %d %lld %lld\n",l,r,lh,rh,tree[root*2],tree[root*2+1]);
if(l == lh && r == rh)
{
tree[root] += value;
lazy[root] += value;
return ;
}
int mid = (l+r)>>1;
if(mid < lh)
update(root*2+1,mid+1,r,lh,rh,value);
else if(mid >= rh)
update(root*2,l,mid,lh,rh,value);
else
{
update(root*2,l,mid,lh,mid,value);
update(root*2+1,mid+1,r,mid+1,rh,value);
}
tree[root] = max(tree[root*2] , tree[root*2+1]);
}
long long query(int root , int l , int r , int lh , int rh , long long value)
{
if(l == r)
{
if(tree[root]>=value) return l;
return -1;
}
Lazy(root);
tree[root] = max(tree[root*2],tree[root*2+1]);
int mid = (l+r)>>1;
if(lh<=l && r<=rh)
{
if(tree[root*2] >= value)
return query(root*2,l,mid,lh,rh,value);
else if(tree[root*2+1] >= value)
return query(root*2+1,mid+1,r,lh,rh,value);
return -1;
}
long long idx;
if(mid < lh)
return query(root*2+1,mid+1,r,lh,rh,value);
else if(mid >= rh)
return query(root*2,l,mid,lh,rh,value);
else
{
idx = query(root*2,l,mid,lh,mid,value);
if(idx != -1)
return idx;
idx = query(root*2+1,mid+1,r,mid+1,rh,value);
if(idx != -1)
return idx;
}
return -1;
}
void Lazy(int root)
{
if(lazy[root])
{
lazy[root*2] += lazy[root];
lazy[root*2+1] += lazy[root];
tree[root*2] += lazy[root];
tree[root*2+1] += lazy[root];
lazy[root] = 0;
}
}
void printf_tree(int root , int l , int r)
{
if(l == r)
{
pr("%lld ",tree[root]); return ;
}
int mid = (l+r)>>1;
printf_tree(root*2,l,mid);
printf_tree(root*2+1,mid+1,r);
}