2 条题解
-
0njnu19200220 (njnu19200220沈泽波) LV 8 @ 2021-01-27 10:32:40
我要先说一声,N方过十万,暴力碾标算,程东阳牛逼!
代码是用线段树完成的。#include<cstdio> #include<algorithm> #include<cstring> using namespace std; typedef long long ll; const ll INFSIM=0x8080808080808080; const int N=100000; template<typename T> void read(T &x){ x=0;int f=1; char ch=getchar(); while (ch<'0'||ch>'9'){ if (ch=='-') f=-1; ch=getchar(); } while (ch>='0'&&ch<='9'){ x=(x*10+ch-'0'); ch=getchar(); } x*=f; } template<typename T> void write(T x){ if (x<0) {x*=-1;putchar('-');} if (x>9) write(x/10); putchar(x%10+'0'); } struct node{ int l,r; ll val,lag; }; class tree{ node a[(N<<2)+5]; #define l(x) a[x].l #define r(x) a[x].r #define val(x) a[x].val #define lag(x) a[x].lag void spread(int p){ val(p<<1)=val(p<<1)+lag(p);val(p<<1|1)=val(p<<1|1)+lag(p); lag(p<<1)+=lag(p);lag(p<<1|1)+=lag(p);lag(p)=0; } public: tree(){ memset(a,0,sizeof(a)); } void build(int p,int l,int r){ l(p)=l;r(p)=r;if (l==r) {read(val(p));return;} int m=(l+r)>>1;build(p<<1,l,m);build(p<<1|1,m+1,r); val(p)=max(val(p<<1),val(p<<1|1)); } ll query(int p,int l,int r){ if (l<=l(p)&&r>=r(p)) return val(p); int m=(l(p)+r(p))>>1;ll ans=INFSIM;spread(p); if (l<=m) ans=max(ans,query(p<<1,l,r)); if (r>m) ans=max(ans,query(p<<1|1,l,r)); return ans; } void add(int p,int l,int r,ll c){ if (l<=l(p)&&r>=r(p)) {val(p)+=c;lag(p)+=c;return;} int m=(l(p)+r(p))>>1;spread(p); if (l<=m) add(p<<1,l,r,c);if (r>m) add(p<<1|1,l,r,c); val(p)=max(val(p<<1),val(p<<1|1)); } }; int main(){ // freopen("try.in","r",stdin); int n,m;read(n);tree t; t.build(1,1,n);read(m); int opt,l,r;ll x; while (m--){ read(opt); if (opt==1){ read(l);read(r);read(x); t.add(1,l,r,x); } else{ read(l);read(r); write(t.query(1,l,r)); putchar('\n'); } } // fclose(stdin); return 0; }
-
02019-04-21 11:06:40@
本题很模板,可以使用很多种数据结构AC,最常用的做法是使用线段树,但也可以采用分块的做法AC,这里放上分块做法。
#define method_1 #ifdef method_1 /* */ #include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<set> #include<map> #include<queue> #include<stack> #include<vector> #include<cstring> #include<cstdlib> using namespace std; typedef long long ll; const int maxn=100000+5; const ll INF=0x3f3f3f3f3f3f3f3fll; ll n,m,blo; ll v[maxn],bl[maxn],atag[maxn]; vector<ll>ve[1000+5]; ll mx[1000+5]; void reset(ll x) { ll maxx=-INF; for(int i=(x-1)*blo+1; i<=min(blo*x,n); i++) { maxx=max(maxx,v[i]); } mx[x]=maxx; } void add(ll l,ll r,ll c) { for(int i=l; i<=min(r,bl[l]*blo); i++) { v[i]+=c; } reset(bl[l]); if(bl[l]!=bl[r]) { for(int i=(bl[r]-1)*blo+1; i<=r; i++) { v[i]+=c; } } reset(bl[r]); for(int i=bl[l]+1; i<=bl[r]-1; i++) { atag[i]+=c; } } ll query(ll l,ll r) { ll maxx=-INF; for(int i=l; i<=min(r,bl[l]*blo); i++) { maxx=max(maxx,v[i]+atag[bl[l]]); } if(bl[l]!=bl[r]) { for(int i=(bl[r]-1)*blo+1; i<=r; i++) { maxx=max(maxx,v[i]+atag[bl[r]]); } } for(int i=bl[l]+1; i<=bl[r]-1; i++) { maxx=max(maxx,mx[i]+atag[i]); } return maxx; } int main() { ios::sync_with_stdio(false); //freopen("河蟹王国.in","r",stdin); cin>>n; blo=sqrt(n); for(int i=1; i<=n; i++) { cin>>v[i]; } for(int i=1; i<=n; i++) { bl[i]=(i-1)/blo+1; } for(int i=1; i<=n; i++) { ve[bl[i]].push_back(v[i]); } for(int i=1; i<=bl[n]; i++) { ll maxx=-INF; for(int j=0; j<ve[i].size(); j++) { maxx=max(maxx,ve[i][j]); } mx[i]=maxx; } /* for(int i=1;i<=bl[n];i++){ cout<<mx[i]<<" ";//2 4 5 } cout<<endl; */ cin>>m; ll k; while(m--) { cin>>k; ll l,r,c; if(k==1) { cin>>l>>r>>c; add(l,r,c); } else { cin>>l>>r; cout<<query(l,r)<<endl; } /* for(int i=1; i<=bl[n]; i++) { cout<<mx[i]<<" ";//2 4 5 } cout<<endl; */ } return 0; } #endif #ifdef method_2 /* */ #endif #ifdef method_3 /* */ #endif
- 1