我覺得這斷不能怪我 一上來給出操作種類和
Solution
60p
容易想到分治
對於整個序列,可以割作三份,分界點爲最大值和最小值
因爲 如果有一個
然鵝,分界點因而要合法地被算入每個區間,所以處理詢問複雜度是
100p
觀察樣例,或是其他詭異的方式,可以斷定:答案的
我們假設 下圖中的
如果
故設
那麼一定有
既然都是正數 我們簡單處理 容易得到
兩式相加
矛盾 所以
所以越小的區間由於越大的區間 得出結論
Code
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define oo 2139062143
#define sqr(x) ((x)*(x))
#define lowbit(x) ((x)&(-x))
#define abs(x) (((x)>=0)?(x):(-(x)))
#define max(x,y) (((x)>(y))?(x):(y))
#define min(x,y) (((x)<(y))?(x):(y))
#define fo(i,x,y) for (ll i = (x);i <= (y);++ i)
#define fd(i,x,y) for (ll i = (x);i >= (y);-- i)
using namespace std;
typedef double db;
typedef long long ll;
const ll N = 100100;
ll n,d[N * 4],a[N],q;
ll type,l,r;
ll bit;
void build(ll n)
{
for(bit=1;bit<=n+1;bit<<=1);//bit = 總節點數目 - 葉子節點數目
for(ll i=bit+1;i<=bit+n;i++) d[i] = abs(a[i - bit + 1] - a[i - bit]);
// scanf("%d",&d[i]);
for(ll i=bit-1;i;i--)
d[i]=max(d[i<<1],d[i<<1|1]);
}
void updata(ll x,ll y)//修改 d[x] 爲 y
{
for(d[x+=bit]=y,x>>=1;x;x>>=1)
d[x]=max(d[x<<1],d[x<<1|1]);
}
ll query(ll s,ll t)//區間 [s,t] 最大值
{
ll ans=0;
for(s+=bit-1,t+=bit+1;s^t^1;s>>=1,t>>=1)
{
if(~s&1) ans=max(ans,d[s^1]);
if(t&1) ans=max(ans,d[t^1]);
}
return ans;
}
ll read()
{
char ch=' ';ll q=0,w=1;
for(;(ch!='-')&&((ch<'0')||(ch>'9'));ch=getchar());
if(ch=='-')w=-1,ch=getchar();
for(;ch>='0' && ch<='9';ch=getchar())q=q*10+ch-48;
ll n=q*w;return n;
}
ll buf[30];
void write(ll x)
{
if (x<0) putchar('-'),x=-x;
buf[0]=0;
while (x) buf[++buf[0]]=x%10,x/=10;
if (!buf[0]) buf[0]=1,buf[1]=0;
while (buf[0]) putchar('0'+buf[buf[0]--]);
}
int main()
{
freopen("lipschitz.in","r",stdin);
freopen("lipschitz.out","w",stdout);
n = read();
fo(i,1,n) a[i] = read();
build(-- n);
q = read();
while (q --)
{
type = read(),l = read(),r = read();
if (type == 0)
{
a[l] = r;
updata(l,abs(a[l + 1] - a[l]));
updata(l - 1,abs(a[l] - a[l - 1]));
continue;
}
write(query(l,r - 1));putchar('\n');
}
}