1. 程式人生 > 其它 >線段樹真TM好玩!!

線段樹真TM好玩!!

2021.8.16

今天是這個暑假第一天北中集訓.

上午,學習了線段樹(區間加法與區間查詢),這是老師上課用的網站:https://www.cnblogs.com/jason2003/p/9676729.html

由於剛入門,只寫了洛谷上的 P3372,附上程式碼:

#include<bits/stdc++.h>
using namespace std;
long long a[4000001],s[4000001],lazy[4000001],ans,n,m,c,c1,c2,c3;
typedef long long ll; 
inline void js(register ll x,register ll l,register ll r)
{
    
if(l==r) { s[x]=a[l]; return; } register ll mid=(l+r)>>1; js(2*x,l,mid); js(2*x+1,mid+1,r); s[x]=s[x*2]+s[2*x+1]; } inline void zd(register ll x,register ll l,register ll r) { register ll mid=(l+r)>>1; s[x*2]+=lazy[x]*(mid-l+1); s[x*2+1
]+=lazy[x]*(r-mid); lazy[2*x]+=lazy[x]; lazy[2*x+1]+=lazy[x]; lazy[x]=0; } inline void xg(register ll x,register ll l,register ll r) { if(r<c1||l>c2) { return; } if(lazy[x]!=0) { zd(x,l,r); } if(l>=c1&&r<=c2) { lazy[x]
+=c3; s[x]+=lazy[x]*(r-l+1); return; } register ll mid=(l+r)>>1; xg(2*x,l,mid); xg(2*x+1,mid+1,r); s[x]=s[x*2]+s[2*x+1]; } inline void cx(register ll x,register ll l,register ll r) { if(r<c1||l>c2) { return; } if(lazy[x]!=0) { zd(x,l,r); } if(l>=c1&&r<=c2) { ans+=s[x]; return; } register ll mid=(l+r)>>1; cx(2*x,l,mid); cx(2*x+1,mid+1,r); } int main() { scanf("%lld%d",&n,&m); for(register ll i=1;i<=n;++i) { scanf("%lld",&a[i]); } js(1,1,n); for(register ll i=1;i<=m;++i) { scanf("%lld",&c); if(c==1) { scanf("%lld%d%d",&c1,&c2,&c3); xg(1,1,n); } if(c==2) { ans=0; scanf("%lld%d",&c1,&c2); cx(1,1,n); printf("%lld\n",ans); } } return 0; }

下午,我們寫了NOIP2016提高組的初賽試題

“提高組的試題”啊,給我們這些普及組的人做!

做的時候好崩潰,特別是最後那些填空題...

但分數還可以,拿到了74分(幸好及格了)