【BZOJ2138】stone

http://darkbzoj.tk/problem/2138

#include<stack>
#include<queue>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#define N 45000
#define ri register int
using namespace std;

int a[N],k[N],sum[N];
int n,m;

inline int read() {
int ret=0,f=0; char ch=getchar();
while (ch<'0' || ch>'9') f|=(ch=='-'),ch=getchar();
while (ch>='0' && ch<='9') ret*=10,ret+=(ch-'0'),ch=getchar();
return f?-ret:ret;
}

int sqr(int x) {
return x*x;
}

struct segment_tree {
int t1[N<<2],t2[N<<2];
int tag1[N<<2],tag2[N<<2];
void maketree(int x,int l,int r) {
if (l==r) {
t1[x]=t2[x]=sum[l];
return;
}
int mid=(l+r)/2;
maketree(x<<1,l,mid); maketree(x<<1|1,mid+1,r);
t1[x]=max(t1[x<<1],t1[x<<1|1]);
t2[x]=min(t2[x<<1],t2[x<<1|1]);
}
void pushdown1(int x) {
int k=tag1[x]; tag1[x]=0;
t1[x<<1]+=k;   tag1[x<<1]+=k;
t1[x<<1|1]+=k; tag1[x<<1|1]+=k;
}
void pushdown2(int x) {
int k=tag2[x]; tag2[x]=0;
t2[x<<1]+=k;   tag2[x<<1]+=k;
t2[x<<1|1]+=k; tag2[x<<1|1]+=k;
}
void modify1(int x,int lb,int rb,int l,int r,int k) {
if (l<=lb && rb<=r) {
t1[x]+=k; tag1[x]+=k;
return;
}
if (l>rb || r<lb) return;
pushdown1(x);
int mid=(lb+rb)/2;
modify1(x<<1,lb,mid,l,r,k); modify1(x<<1|1,mid+1,rb,l,r,k);
t1[x]=max(t1[x<<1],t1[x<<1|1]);
}
void modify2(int x,int lb,int rb,int l,int r,int k) {
if (l<=lb && rb<=r) {
t2[x]+=k; tag2[x]+=k;
return;
}
if (l>rb || r<lb) return;
pushdown2(x);
int mid=(lb+rb)/2;
modify2(x<<1,lb,mid,l,r,k); modify2(x<<1|1,mid+1,rb,l,r,k);
t2[x]=min(t2[x<<1],t2[x<<1|1]);
}
int query1(int x,int lb,int rb,int l,int r) {
if (l<=lb && rb<=r) return t1[x];
if (l>rb || r<lb) return -1e9;
pushdown1(x);
int mid=(lb+rb)/2;
return max(query1(x<<1,lb,mid,l,r),query1(x<<1|1,mid+1,rb,l,r));
}
int query2(int x,int lb,int rb,int l,int r) {
if (l<=lb && rb<=r) return t2[x];
if (l>rb || r<lb) return 1e9;
pushdown2(x);
int mid=(lb+rb)/2;
return min(query2(x<<1,lb,mid,l,r),query2(x<<1|1,mid+1,rb,l,r));
}
} T;

int main() {
for (ri i=1;i<=n;i++) a[i]=(sqr(i-x)+sqr(i-y)+sqr(i-z))%p;
for (ri i=3;i<=m;i++) k[i]=(x*k[i-1]+y*k[i-2]+z)%p;
for (ri i=1;i<=n;i++) sum[i]=sum[i-1]+a[i];
T.maketree(1,1,n);
for (ri i=1;i<=m;i++) {
k[i]=min(k[i],T.query2(1,1,n,r,n)-max(T.query1(1,1,n,1,l-1),0));
printf("%d\n",k[i]);
T.modify1(1,1,n,l,n,-k[i]); T.modify2(1,1,n,r,n,-k[i]);
}
return 0;
}

posted @ 2019-08-08 21:14  HellPix  阅读(169)  评论(0编辑  收藏  举报