hdu4533 线段树维护分段函数

更新:x1,y1,x2,y2不用long long 会wa。。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
#define maxn 200005
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define ll long long 
ll A[maxn<<2],B[maxn<<2],C[maxn<<2];//系数a,b,c在t[l,r]区间的取值

inline void pushdown(int rt){
    A[rt<<1]+=A[rt];A[rt<<1|1]+=A[rt];
    B[rt<<1]+=B[rt];B[rt<<1|1]+=B[rt];
    C[rt<<1]+=C[rt];C[rt<<1|1]+=C[rt];
    A[rt]=B[rt]=C[rt]=0;
}
//区间【L,R】的a,b,c更新
void update(int L,int R,int l,int r,int rt,ll a,ll b,ll c){
    if(L<=l && R>=r){
        A[rt]+=a;
        B[rt]+=b;
        C[rt]+=c;
        return;
    }
    int m=l+r>>1;
    if(L<=m) update(L,R,lson,a,b,c);
    if(R>m) update(L,R,rson,a,b,c);
}
//询问t小于等于pos的一元二次式的值
ll query(ll t,int l,int r,int rt){
    if(l==r){
        return A[rt]*t*t+B[rt]*t+C[rt];
    }
    pushdown(rt);
    int m=l+r>>1;
    if(t<=m) return query(t,lson);
    else return query(t,rson);
}
void solve(ll x1,ll y1,ll x2,ll y2){
    //t如果大于max(x2,y2),那么就是覆盖了整块被子,此时a,b皆为0
    update(max(x2,y2)+1,maxn,1,maxn,1,0,0,(x2-x1)*(y2-y1));
    //a为0的状态
    if(x2<y2)//t先触碰到右边,那么t在max(x2,y1)+1到y2之间一直是线性增长的
        update(max(x2,y1)+1,y2,1,maxn,1,0,x2-x1,y1*(x1-x2));
    else //t先触碰到上边,那么t在max(x1,y2)+1到x2之间一直是线性增长的
        update(max(x1,y2)+1,x2,1,maxn,1,0,-y1+y2,x1*(y1-y2));
    //最后的情况,三个系数都不是0
    if(max(x1,y1)<min(x2,y2))
        update(max(x1,y1),min(x2,y2),1,maxn,1,1,-(x1+y1),x1*y1);
}
int main(){
    int T,N;
    ll x,t;
    ll x1,y1,x2,y2;
    cin >> T;
    while(T--){
        memset(A,0,sizeof A);
        memset(B,0,sizeof B);
        memset(C,0,sizeof C);
        
        scanf("%d",&N);
        for(int i=1;i<=N;i++){
            scanf("%lld%lld%lld%lld",&x1,&y1,&x2,&y2);
            solve(x1,y1,x2,y2);
        }
        scanf("%lld",&x);
        while(x--){
            scanf("%lld",&t);
            printf("%lld
",query(t,1,maxn,1));
        }
    }
    return 0;
}

wa了,为什么呢

/**
推公式就完事了
要推出关于t的一元二次方程的值a,b,c关于t的函数,即t的分段函数
*/
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
#define maxn 200005
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define ll long long 
ll A[maxn<<2],B[maxn<<2],C[maxn<<2];//系数a,b,c在t[l,r]区间的取值

inline void pushdown(int rt){
    A[rt<<1]+=A[rt];A[rt<<1|1]+=A[rt];
    B[rt<<1]+=B[rt];B[rt<<1|1]+=B[rt];
    C[rt<<1]+=C[rt];C[rt<<1|1]+=C[rt];
    A[rt]=B[rt]=C[rt]=0;
}
//区间【L,R】的a,b,c更新
void update(int L,int R,int l,int r,int rt,ll a,ll b,ll c){
    if(L<=l && R>=r){
        A[rt]+=a;
        B[rt]+=b;
        C[rt]+=c;
        return;
    }
    int m=l+r>>1;
    if(L<=m) update(L,R,lson,a,b,c);
    if(R>m) update(L,R,rson,a,b,c);
}
//询问t小于等于pos的一元二次式的值
ll query(ll t,int l,int r,int rt){
    if(l==r){
        return A[rt]*t*t+B[rt]*t+C[rt];
    }
    pushdown(rt);
    int m=l+r>>1;
    if(t<=m) return query(t,lson);
    else return query(t,rson);
}
void solve(int x1,int y1,int x2,int y2){
    //t如果大于max(x2,y2),那么就是覆盖了整块被子,此时a,b皆为0
    update(max(x2,y2)+1,maxn,1,maxn,1,0,0,(x2-x1)*(y2-y1));
    //a为0的状态
    if(x2<y2)//t先触碰到右边,那么t在max(x2,y1)+1到y2之间一直是线性增长的
        update(max(x2,y1)+1,y2,1,maxn,1,0,x2-x1,y1*(x1-x2));
    else //t先触碰到上边,那么t在max(x1,y2)+1到x2之间一直是线性增长的
        update(max(x1,y2)+1,x2,1,maxn,1,0,-y1+y2,x1*(y1-y2));
    //最后的情况,三个系数都不是0
    if(max(x1,y1)<min(x2,y2))
        update(max(x1,y1),min(x2,y2),1,maxn,1,1,-(x1+y1),x1*y1);
}
int main(){
    int T,N;
    ll x,t;
    int x1,y1,x2,y2;
    cin >> T;
    while(T--){
        memset(A,0,sizeof A);
        memset(B,0,sizeof B);
        memset(C,0,sizeof C);
        
        scanf("%d",&N);
        for(int i=1;i<=N;i++){
            scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
            solve(x1,y1,x2,y2);
        }
        scanf("%lld",&x);
        while(x--){
            scanf("%lld",&t);
            printf("%lld
",query(t,1,maxn,1));
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/zsben991126/p/9932617.html