1. 程式人生 > >hdu4533 線段樹維護分段函式

hdu4533 線段樹維護分段函式

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\n",query(t,1,maxn,1)); } } return 0; }