Joker_IV @ 2024-10-30 19:03:49
代码如下(AC #1 # 3)
#include <bits/stdc++.h>
using namespace std;
#define MAXN 8000010
#define int long long
#define zero -1e17
long long a[MAXN],t[MAXN],lzy[MAXN],n,q,cover[MAXN];
bool inrange(int L,int R,int l,int r){
return l<=L&&R<=r;
}
bool outrange(int L,int R,int l,int r){
return(l>R||r<L);
}
void build(const int u,int L,int R){
if(L==R){
t[u]=a[L];
cover[u]=a[L];
lzy[u]=0;
return;
}
int mid=(R+L)>>1;
build(u*2,L,mid);build(u*2+1,mid+1,R);
t[u]=max(t[u*2],t[u*2+1]);
}
void maketag(int u,long long k,int type){
if(type==1){
t[u]=k;
cover[u]=k;
lzy[u]=0;
}
else{
t[u]+=k;
if(cover[u]==zero){
lzy[u]+=k;
}
else{
cover[u]+=k;
}
}
}
void pushdown(int u){
if(cover[u]!=zero){
maketag(u*2,cover[u],1);
maketag(u*2+1,cover[u],1);
cover[u]=zero;
}
else if(lzy[u]){
maketag(u*2,lzy[u],2);
maketag(u*2+1,lzy[u],2);
lzy[u]=0;
}
}
void update(int u,int L,int R,int l,int r,int k,int type){
if(inrange(L,R,l,r) && cover[u] != zero){
maketag(u,k,type);
return;
}
if(!outrange(L,R,l,r)){
int mid=(L+R)/2;
pushdown(u);
update(u*2,L,mid,l,r,k,type);update(u*2+1,mid+1,R,l,r,k,type);
t[u]=max(t[u*2],t[u*2+1]);
}
}
long long ask(int u,int L,int R,int l,int r){
if(inrange(L,R,l,r))return t[u];
if(!outrange(L,R,l,r)){
int mid=(L+R)/2, ma = zero;
pushdown(u);
if (mid >=l)ma = max(ma, ask(u*2,L,mid,l,r));
if (mid <r) ma = max(ma,ask(u*2+1,mid+1,R,l,r));
return ma;
}
else return zero;
}
signed main(){
freopen("1.in", "r", stdin);
scanf("%lld%lld",&n,&q);
for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
build(1,1,n);
while(q--){
int x,y,k;
int op;
scanf("%d%d%d",&op,&x,&y);
if(op==1||op==2){
scanf("%d",&k);
update(1,1,n,x,y,k,op);
}
else if(op==3){
printf("%lld\n",ask(1,1,n,x,y));
}
}
return 0;
}
by INKC @ 2024-11-01 22:22:14
过了吗 我也遇到这个问题了
by pengbonan @ 2024-11-04 17:21:04
by MTEzNUc3 @ 2024-11-10 17:56:49
by niuqichongtian @ 2024-11-14 00:17:00
20pts++
by niuqichongtian @ 2024-11-14 00:35:40
@Joker_IV 你pushdown里面
void pushdown(int u){
if(cover[u]!=zero){
maketag(u*2,cover[u],1);
maketag(u*2+1,cover[u],1);
cover[u]=zero; // 这里确定不把lzy[u]改一下?
}
else if(lzy[u]){
maketag(u*2,lzy[u],2);
maketag(u*2+1,lzy[u],2);
lzy[u]=0;
}
}
从马蜂来看,深入浅出进阶篇人手一本了
by niuqichongtian @ 2024-11-14 00:38:29
AC了
记录
@Joker_IV
@INKC
@pengbonan
@MTEzNUc3
by niuqichongtian @ 2024-11-14 01:10:19
从楼主的代码里发现:
void maketag(int u,long long k,int type){
if(type==1){
t[u]=k;
cover[u]=k;
lzy[u]=0;
}
else{
t[u]+=k;
if(cover[u]==zero){
lzy[u]+=k;
}
else{
cover[u]+=k;
}
}
}
这段代码当中,所有人包括我都有一个误区:
不要脸的求个关注
by niuqichongtian @ 2024-11-14 01:15:28
@niuqichongtian 唉不对,怎么样例都没过
by niuqichongtian @ 2024-11-14 02:12:29
@Joker_IV 你代码太神奇了 我加了个输出,并且
void build(const int u,int L,int R){
if(L==R){
t[u]=a[L];
cover[u]=a[L];
lzy[u]=0;
return;
}
int mid=(R+L)>>1;
build(u*2,L,mid);build(u*2+1,mid+1,R);
t[u]=max(t[u*2],t[u*2+1]);
}
void maketag(int u,long long k,int type,int k2=0){
if(type==1){
t[u]=k;
cover[u]=k;
lzy[u]=k2;
}
else{
t[u]+=k;
// if(cover[u]==zero){
lzy[u]+=k;
// }
// else{
// cover[u]+=k;
// }
}
}
改了
于是呼,样例对了
输出注释掉
样例错了
然后整了个
signed main(){
// freopen("1.in", "r", stdin);
scanf("%lld%lld",&n,&q);
for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
for (int i = 1; i <= n; i++)
ask(1, 1, n, i, i);
build(1,1,n);
while(q--){
int x,y,k;
int op;
scanf("%lld%lld%lld",&op,&x,&y);
if(op==1||op==2){
scanf("%lld",&k);
update(1,1,n,x,y,k,op);
}
else if(op==3){
printf("%lld\n",ask(1,1,n,x,y));
}
}
return 0;
}
40pts,TLE一片
#include <bits/stdc++.h>
using namespace std;
#define MAXN 8000010
#define int long long
#define zero -1e17
long long a[MAXN],t[MAXN],lzy[MAXN],n,q,cover[MAXN];
bool inrange(int L,int R,int l,int r) {
return l<=L&&R<=r;
}
bool outrange(int L,int R,int l,int r) {
return(l>R||r<L);
}
void build(int u,int L,int R) {
cover[u] = zero;
lzy[u] = 0;
if(L==R) {
t[u]=a[L];
cover[u]=a[L];
lzy[u]=0;
return;
}
int mid=(R+L)>>1;
build(u*2,L,mid);
build(u*2+1,mid+1,R);
t[u]=max(t[u*2],t[u*2+1]);
// printf("t[%d]=%d\n", u, t[u]);
}
void maketag(int u,long long k,int k2) {
// if (u == 3)
// cout << k << " " << k2 << endl;
if(k != zero) {
t[u]=k+k2;
cover[u]=k;
lzy[u]=k2;
} else {
t[u]+=k2;
lzy[u]+=k2;
}
// if (u == 3)
// cout << t[u] << " I AK IOI!!! !!! !!!" << endl;
}
void pushdown(int u) {
// if(cover[u]!=zero) {
// maketag(u*2,cover[u],1,lzy[u]);
// maketag(u*2+1,cover[u],1,lzy[u]);
// } else if(lzy[u]) {
maketag(u*2,cover[u],lzy[u]);
maketag(u*2+1,cover[u],lzy[u]);
// }
cover[u]=zero;
lzy[u]=0;
}
void update(int u,int L,int R,int l,int r,int k,int type) {
if(inrange(L,R,l,r)) {
if (type==1)
maketag(u,k,0);
else
maketag(u,zero,k);
return;
}
if(!outrange(L,R,l,r)) {
int mid=(L+R)>>1;
pushdown(u);
update(u*2,L,mid,l,r,k,type);
update(u*2+1,mid+1,R,l,r,k,type);
t[u]=max(t[u*2],t[u*2+1]);
// printf("t[%lld] [%lld, %lld] = %lld when finding [%lld, %lld]\n", u, L, R, t[u], l, r);
}
}
long long ask(int u,int L,int R,int l,int r) {
if(inrange(L,R,l,r))return t[u];
if(!outrange(L,R,l,r)) {
long long mid=(L+R)/2, ma = zero;
pushdown(u);
// cout << cover[u] << " " << lzy[u] << " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" << endl;
if (mid >=l)ma = max(ma, ask(u*2,L,mid,l,r));
if (mid <=r) ma = max(ma,ask(u*2+1,mid+1,R,l,r));
// printf("t[%lld] [%lld, %lld] = %lld when finding [%lld, %lld]\n", u, L, R, ma, l, r);
return max(ask(u*2,L,mid,l,r), ask(u*2+1,mid+1,R,l,r));
} else return zero;
}
signed main() {
// freopen("1.in", "r", stdin);
scanf("%lld%lld",&n,&q);
for(int i=1; i<=n; i++)scanf("%lld",&a[i]);
build(1,1,n);
// for (int i = 1; i <= n; i++)
// ask(1, 1, n, i, i);
while(q--) {
int x,y,k;
int op;
scanf("%lld%lld%lld",&op,&x,&y);
if(op==1||op==2) {
scanf("%lld",&k);
update(1,1,n,x,y,k,op);
} else if(op==3) {
printf("%lld\n",ask(1,1,n,x,y));
}
}
return 0;
}
by niuqichongtian @ 2024-11-14 13:34:40
问题总结
t[u] = current_cover + current_adding