2 条题解

  • 0

    我要先说一声,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;
    }
    
  • 0
    @ 2019-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

信息

ID
1045
难度
3
分类
数据结构 | 线段树 点击显示
标签
(无)
递交数
54
已通过
27
通过率
50%
上传者