若该序列是先辈,假设取长度为k的后缀,则该序列中前k个元素都比其长度为k的后缀屑,因此不难得出先辈一定是一个非递减序列。因此题目的询问变成求一个序列是否为非递减序列,用线段树维护。
我的第一个想法,就是区间修改,然后根据要查询的区间对线段树中每个点单点查询,之后再判断是否是非递减序列。
代码如下:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1e6+10;
typedef long long LL;
int n,m,w[N];
struct node
{
int l,r;
LL v;
LL add;
}tr[4*N];
void pushup(int u)
{
tr[u].v=tr[u<<1].v+tr[u<<1|1].v;
}
void build(int u,int l,int r)
{
if(l==r)
{
tr[u]={
l,r,w[l],0};
return;
}
tr[u]={
l,r};
int mid=l+r>>1;
build(u<<1,l,mid);
build(u<<1|1,mid+1,r);
pushup(u);
}
void pushdown(int u)
{
if(tr[u].add)
{
tr[u<<1].add+=tr[u].add;
tr[u<<1|1].add+=tr[u].add;
tr[u<<1].v+=(tr[u<<1].r-tr[u<<1].l+1)*tr[u].add;
tr[u<<1|1].v+=(tr[u<<1|1].r-tr[u<<1|1].l+1)*tr[u].add;
tr[u].add=0;
}
}
void modify(int u,int l,int r,int c)
{
if(tr[u].l>=l&&tr[u].r<=r)
{
tr[u].add+=c;
tr[u].v+=(tr[u].r-tr[u].l+1)*c;
return;
}
pushdown(u);
int mid=tr[u].l+tr[u].r>>1;
if(l<=mid)