md,,好久没写线段树了,,犯了很多脑残错误,,哎,,
唔,,,写完还心情好,用分块的做法重新写了遍,,,
主要是怎么查找一个区间内大于大于V的第一个元素,分块比较好想,块内暴力就好了
然后,,线段树那,,有一种想法就是用二分查找这个位置,,比如我现在找[l,m]这个区间最大值是不是大于v,是的话,继续划分[l,m],如果不是大于等于v,继续划分[m+1,r]。
这种正确性很显然。
还有一种,是我写的,,我,,解释不太清楚,,(捂脸
线段树做法:
#include<iostream>
#include<cstdio>
#include<math.h>
#include<algorithm>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<queue>
#include<string.h>
#include<cstring>
#include<vector>
#include<time.h>
#include<stdlib.h>
using namespace std;
#define INF 0x3f3f3f3f
#define INFLL 0x3f3f3f3f3f3f3f3f
#define FIN freopen("input.txt","r",stdin);
#define mem(x,y) memset(x,y,sizeof(x));
typedef unsigned long long ULL;
typedef long long LL;
#define fuck(x) cout<<x<<endl;
#define MX 111111
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
typedef pair<pair<int,int>,int> PIII;
typedef pair<int,int> PII;
int n,m;
LL maxn[MX<<2],lazy[MX<<2];
void pushup(int rt)
{
maxn[rt]=max(maxn[rt<<1],maxn[rt<<1|1]);
}
void build(int l,int r,int rt)
{
lazy[rt]=0;
if(l==r)
{
scanf("%lld",&maxn[rt]);
return ;
}
int m=(l+r)>>1;
build(lson);
build(rson);
pushup(rt);
}
void pushdown(int rt)
{
if(lazy[rt])
{
lazy[rt<<1]+=lazy[rt];
lazy[rt<<1|1]+=lazy[rt];
maxn[rt<<1]+=lazy[rt];
maxn[rt<<1|1]+=lazy[rt];
}
lazy[rt]=0;
}
void update(int d,int L,int R,int l,int r,int rt)
{
if(L<=l&&R>=r)
{
lazy[rt]+=d;
maxn[rt]+=d;
return ;
}
pushdown(rt);
int m=(l+r)>>1;
if(m>=L)update(d,L,R,lson);
if(m+1<=R) update(d,L,R,rson);
pushup(rt);
}
int query(int v,int L,int R,int l,int r,int rt)
{
if(l==r) return l;
pushdown(rt);
int m=(l+r)>>1;
int ans=-1;
if(m>=L&&maxn[rt<<1]>=v)ans=query(v,L,R,lson);
if(ans==-1)if(m+1<=R&&maxn[rt<<1|1]>=v) ans=query(v,L,R,rson);
return ans;
}
int main()
{
int cas;
cin>>cas;
while(cas--)
{
cin>>n>>m;
build(1,n,1);
for(int i=1; i<=m; i++)
{
int opt,l,r,v;
scanf("%d%d%d%d",&opt,&l,&r,&v);
if(opt==1)printf("%d\n",query(v,l,r,1,n,1));
else update(v,l,r,1,n,1);
}
}
return 0;
}
分块的做法(其实差不多就是模拟线段树的,,)
#include<iostream>
#include<cstdio>
#include<math.h>
#include<algorithm>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<queue>
#include<string.h>
#include<cstring>
#include<vector>
#include<time.h>
#include<stdlib.h>
using namespace std;
#define INF 0x3f3f3f3f
#define INFLL 0x3f3f3f3f3f3f3f3f
#define FIN freopen("input.txt","r",stdin);
#define mem(x,y) memset(x,y,sizeof(x));
typedef unsigned long long ULL;
typedef long long LL;
#define fuck(x) cout<<x<<endl;
#define MX 111111
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
typedef pair<pair<int,int>,int> PIII;
typedef pair<int,int> PII;
int n,m;
int block,blocknum,belong[MX],blockl[MX],blockr[MX];
LL maxn[MX],arr[MX],lazy[MX];
void pushdown(int x)
{
if(lazy[x])
for(int i=blockl[x]; i<=blockr[x]; i++)arr[i]+=lazy[x];
lazy[x]=0;
}
void pushup(int x)
{
for(int i=blockl[x]; i<=blockr[x]; i++)maxn[x]=max(maxn[x],arr[i]);
}
int main()
{
int cas;
cin>>cas;
while(cas--)
{
cin>>n>>m;
for(int i=1; i<=n; i++)scanf("%lld",&arr[i]);
block=sqrt(n+0.5);
blocknum=(n-1)/block+1;
for(int i=1; i<=n; i++) belong[i]=(i-1)/block+1;
for(int i=1; i<=blocknum; i++)
{
blockl[i]=(i-1)*block+1;
if(i==blocknum) blockr[i]=n;
else blockr[i]=i*block;
}
for(int i=1; i<=blocknum; i++)maxn[i]=-INF,lazy[i]=0;
for(int i=1; i<=n; i++)
{
maxn[belong[i]]=max(maxn[belong[i]],arr[i]);
}
for(int i=1; i<=m; i++)
{
int opt,l,r,v;
scanf("%d%d%d%d",&opt,&l,&r,&v);
if(opt==1)
{
int x=-1;
if(belong[l]==belong[r])
{
pushdown(belong[l]);
for(int i=l; i<=r; i++)if(arr[i]>=v)
{
x=i;
break;
}
}
else
{
pushdown(belong[l]);
for(int i=l; i<=blockr[belong[l]]; i++)
{
if(arr[i]>=v)
{
x=i;
break;
}
}
if(x==-1)for(int i=belong[l]+1; i<=belong[r]-1; i++)
{
if(maxn[i]>=v)
{
pushdown(i);
for(int j=blockl[i]; j<=blockr[i]; j++)
{
if(arr[j]>=v)
{
x=j;
break;
}
}
}
if(x!=-1)break;
}
if(x==-1)
{
pushdown(belong[r]);
for(int i=blockl[belong[r]]; i<=r; i++) if(arr[i]>=v)
{
x=i;
break;
}
}
}
printf("%d\n",x);
}
else
{
if(belong[l]==belong[r])
{
pushdown(belong[l]);
for(int i=l; i<=r; i++) arr[i]+=v;
pushup(belong[l]);
}
else
{
pushdown(belong[l]);
for(int i=l; i<=blockr[belong[l]]; i++)arr[i]+=v;
pushup(belong[l]);
for(int i=belong[l]+1; i<=belong[r]-1; i++)
{
lazy[i]+=v;
maxn[i]+=v;
}
pushdown(belong[r]);
for(int i=blockl[belong[r]]; i<=r; i++) arr[i]+=v;
pushup(belong[r]);
}
}
}
}
return 0;
}