ANSI C 线段树模板
2017-12-31 14:21
295 查看
线段树维护区间+x,区间查询区间和。Coded under gcc。
SEGT.cpp
#include<cstdio> #include<cstdlib> #include<algorithm> using namespace std; const int maxn=1000000+10; namespace segT{ int lch[maxn],rch[maxn],lst[maxn],rst[maxn]; int sum[maxn],lazy[maxn],ncnt=0,a[maxn/4]; void build(int t,int ls,int rs){ if(ls==rs){ lch[t]=rch[t]=0;lst[t]=rst[t]=ls; sum[t]=a[ls];lazy[t]=0; }else{ int mid=(ls+rs)/2,nl=++ncnt,nr=++ncnt; build(nl,ls,mid);build(nr,mid+1,rs); lch[t]=nl;rch[t]=nr; lst[t]=ls;rst[t]=rs; sum[t]=sum[nl]+sum[nr]; lazy[t]=0; } } int query(int t,int ls,int rs){ if(lst[t]>rs || rst[t]<ls)return 0; if(ls<=lst[t]&&rst[t]<=rs)return sum[t]; int nl=lch[t],nr=rch[t]; if(lazy[t]!=0){ lazy[nl]+=lazy[t];lazy[nr]+=lazy[t]; sum[nl]+=(rst[nl]-lst[nl]+1)*lazy[t]; sum[nr]+=(rst[nr]-lst[nr]+1)*lazy[t]; lazy[t]=0; } return query(nl,ls,rs)+query(nr,ls,rs); } void segadd(int t,int ls,int rs,int v){ if(lst[t]>rs || rst[t]<ls)return; if(ls<=lst[t]&&rst[t]<=rs){ lazy[t]+=v; sum[t]+=(rst[t]-lst[t]+1)*v; return; } int nl=lch[t],nr=rch[t]; if(lazy[t]!=0){ lazy[nl]+=lazy[t];lazy[nr]+=lazy[t]; sum[nl]+=(rst[nl]-lst[nl]+1)*lazy[t]; sum[nr]+=(rst[nr]-lst[nr]+1)*lazy[t]; lazy[t]=0; } segadd(nl,ls,rs,v);segadd(nr,ls,rs,v); sum[t]=sum[nl]+sum[nr];//maintain !!!! } void debugT(){ for(int i=1;i<=ncnt;i++){ printf("[%3d] %5d %5d %5d %5d %5d\n" ,i,lch[i],rch[i],lst[i],rst[i],sum[i]); } } } int main(){ int n,q;scanf("%d%d",&n,&q); for(int i=1;i<=n;i++)scanf("%d",&segT::a[i]); int root=++segT::ncnt;segT::build(root,1,n); for(int i=1;i<=q;i++){ int op;scanf("%d",&op); if(op==1){ int l,r;scanf("%d%d",&l,&r); printf("%d\n",segT::query(root,l,r)); }else if(op==2){ int l,r,v;scanf("%d%d%d",&l,&r,&v); segT::segadd(root,l,r,v); } } return 0; }
bforce.cpp 暴力程序
#include<cstdio> #include<cstdlib> #include<algorithm> using namespace std; int a[10000+10]; int sum(int l,int r){ int ans=0; for(int i=l;i<=r;i++) ans+=a[i]; return ans; } int add(int l,int r,int v){ for(int i=l;i<=r;i++) a[i]+=v; } int main(){ int n,q;scanf("%d%d",&n,&q); for(int i=1;i<=n;i++)scanf("%d",&a[i]); for(int i=1;i<=q;i++){ int op;scanf("%d",&op); if(op==1){ int l,r;scanf("%d%d",&l,&r); printf("%d\n",sum(l,r)); }else if(op==2){ int l,r,v;scanf("%d%d%d",&l,&r,&v); add(l,r,v); } } return 0; }
data.cpp 数据生成器
#include<cstdio> #include<cstdlib> #include<algorithm> using namespace std; #include<ctime> int rand(int L,int R){return rand()%(R-L+1)+L;} int main(){ srand(time(NULL)); int n=rand(1000,3000),q=rand(1000,3000); printf("%d %d\n",n,q); for(int i=1;i<=n;i++)printf("%d ",rand(1,100)); putchar('\n'); for(int i=1;i<=q;i++){ int op=rand(1,2);printf("%d ",op); if(op==1){ int l=rand(1,n),r=rand(l,n); printf("%d %d\n",l,r); }else{ int l=rand(1,n),r=rand(l,n),v=rand(-10,10); printf("%d %d %d\n",l,r,v); } } return 0; }
try.bat 对拍程序
@echo off set /a i=1 :begin if %i% GTR 100 goto end data.exe > input.txt SEGT.exe < input.txt > output.txt bforce.exe < input.txt > std.txt fc std.txt output.txt if errorlevel 1 pause set /a i=i+1 goto begin :end echo [end] pause
相关文章推荐
- 啊好久没写了- -。。。 现在又开始系统的刷题了,所以还是写写吧- - 首先附上第一道线段树模板题- -。。。
- HDU(1166),线段树模板,单点更新,区间总和
- P3373 【模板】线段树 2
- Water Tree CodeForces - 343D(dfs序列+线段树 模板)
- 线段树模板
- 线段树模板
- hdu1166 敌兵布阵+线段树模板题+单点修改
- 线段树模板
- 线段树模板 HDU-1166
- 线段树模板
- 【南阳oj 108士兵杀敌(一)】 (线段树 模板题)
- 线段树 + 区间更新 + 模板 ---- poj 3468
- HDU1754 I Hate it 线段树模板题
- 线段树单点更新模板-杭电1166
- 线段树模板
- 线段树模板
- hdu1166(线段树单点更新&区间求和模板)
- poj 3264 Balanced Lineup(线段树模板)
- HDU 1754 B I Hate It 线段树 单点更新 区间最大值 模板
- hdu1166(线段树模板题)