4 条题解

  • 1
    @ 2023-10-26 19:38:05
    #include <bits/stdc++.h>
    #define int long long
    using namespace std;
    const int N = 100005 , SN = 1005;
    
    int n , m , a[ N ];
    int lenb;
    int q[ N ] , st[ SN ] , ed[ SN ];
    int sum[ SN ] , add[ SN ];
    
    void modify( int l , int r , int v )
    {
    	int lx = q[ l ] , rx = q[ r ];
    	
    	if( lx == rx )
    	{
    		sum[ lx ] += v * ( r - l + 1 );
    		for( int i = l ; i <= r ; i ++ )
    			a[ i ] += v;
    		return;
    	}
    	
    	sum[ lx ] += v * ( ed[ lx ] - l + 1 );
    	for( int i = l ; i <= ed[ lx ] ; i ++ )
    		a[ i ] += v;
    	
    	for( int i = lx + 1 ; i <= rx - 1 ; i ++ )
    		add[ i ] += v;
    	
    	sum[ rx ] += v * ( r - st[ rx ] + 1 ); 
    	for( int i = st[ rx ] ; i <= r ; i ++ ) 
    		a[ i ] += v;
    }
    
    int query( int l , int r )
    {
    	int lx = q[ l ] , rx = q[ r ] , ans = 0;
    	
    	if( lx == rx )
    	{
    		ans += add[ lx ] * ( r - l + 1 );
    		for( int i = l ; i <= r ; i ++ )
    			ans += a[ i ];
    		return ans;
    	}
    	
    	ans += add[ lx ] * ( ed[ lx ] - l + 1 );
    	for( int i = l ; i <= ed[ lx ] ; i ++ )
    		ans += a[ i ];
    	
    	for( int i = lx + 1 ; i <= rx - 1 ; i ++ )
    		ans += sum[ i ] + add[ i ] * lenb;
    	
    	ans += add[ rx ] * ( r - st[ rx ] + 1 ); 
    	for( int i = st[ rx ] ; i <= r ; i ++ )
    		ans += a[ i ];
    	
    	return ans;
    }
    
    void init()
    {
    	lenb = sqrt( n );
    	for( int i = 1 ; i <= ceil( 1.0 * n / lenb ) ; i ++ )
    	{
    		st[ i ] = ( i - 1 ) * lenb + 1;
    		ed[ i ] = min( i * lenb , n );
    		for( int j = st[ i ] ; j <= ed[ i ] ; j ++ )
    			q[ j ] = i , sum[ i ] += a[ j ];
    	}
    }
    
    signed main()
    {
    	cin >> n;
    	for( int i = 1 ; i <= n ; i ++ )
    		scanf( "%lld" , a + i );
    	init();
    	
    	cin >> m;
    	while( m -- )
    	{
    		int opt , l , r , v;
    		scanf( "%lld%lld%lld" , & opt , & l , & r );
    		
    		if( opt == 1 )
    		{
    			scanf( "%lld" , & v );
    			modify( l , r , v );
    		}
    		
    		if( opt == 2 )
    		{
    			printf( "%lld\n" , query( l , r ) );
    		}
    	}
    	
    	return 0;
    }
    
    • 0
      @ 2023-11-7 19:56:28

      线段树解法代码:

      #include <bits/stdc++.h>
      using namespace std;
      const int maxn = 2e5 + 5;
      int n, q;
      long long lazy[maxn<<2], tr[maxn<<2];
      
      #define lson l, mid, rt<<1
      #define rson mid+1, r, rt<<1|1
      void push_up(int rt) {
      	tr[rt] = tr[rt<<1] + tr[rt<<1|1];
      }
      void push_down(int l, int r, int rt) {
      	if (lazy[rt]) {
      		int mid = (l + r) / 2;
      		tr[rt<<1] += (mid - l + 1) * lazy[rt];
      		lazy[rt<<1] += lazy[rt];
      		tr[rt<<1|1] += (r - mid) * lazy[rt];
      		lazy[rt<<1|1] += lazy[rt];
      		lazy[rt] = 0;
      	}
      }
      void build(int l, int r, int rt) {
      	if (l == r) {
      		scanf("%lld", tr + rt);
      		return;
      	}
      	int mid = (l + r) / 2;
      	build(lson);
      	build(rson);
      	push_up(rt);
      }
      void update(int L, int R, long long x, int l, int r, int rt) {
      	if (L <= l && r <= R) {
      		tr[rt] += (r - l + 1) * x;
      		lazy[rt] += x;
      		return;
      	}
      	push_down(l, r, rt);
      	int mid = (l + r) / 2;
      	if (L <= mid) update(L, R, x, lson);
      	if (R > mid) update(L, R, x, rson);
      	push_up(rt);
      }
      long long query(int L, int R, int l, int r, int rt) {
      	if (L <= l && r <= R)
      		return tr[rt];
      	push_down(l, r, rt);
      	int mid = (l + r) / 2;
      	long long res = 0;
      	if (L <= mid) res += query(L, R, lson);
      	if (R > mid) res += query(L, R, rson);
      	return res;
      }
      int main() {
      	scanf("%d", &n);
      	build(1, n, 1);
      	scanf("%d", &q);
      	while (q--) {
      		int op, l, r, x;
      		scanf("%d%d%d", &op, &l, &r);
      		if (op == 1) {
      			scanf("%d", &x);
      			update(l, r, x, 1, n, 1);
      		}
      		else 
      			printf("%lld\n", query(l, r, 1, n, 1));
      	}
      	return 0;
      }
      
      • 0
        @ 2023-11-7 19:56:07

        线段树求区间和

        #include<bits/stdc++.h>
        #define ll long long
        #define lson l,mid,rt<<1
        #define rson mid+1,r,rt<<1|1
        using namespace std;
        const int N=2e5+5;
        ll tr[N<<2],a[N];
        ll lazy[N<<2];
        void push_up(int rt)
        {
        	tr[rt]=tr[rt<<1]+tr[rt<<1|1];
        }
        void push_down(int l,int r,int rt)
        {
        	if(lazy[rt])
        	{
        		int mid=(l+r)>>1;
        		tr[rt<<1]+=(mid-l+1)*lazy[rt];
        		lazy[rt<<1]+=lazy[rt];
        		tr[rt<<1|1]+=(r-mid)*lazy[rt];
        		lazy[rt<<1|1]+=lazy[rt];
        		lazy[rt]=0;
        	}
        }
        void build(int l,int r,int rt)
        {
        	if(l==r)
        	{
        		tr[rt]=a[l];
        		return;
        	}
        	int mid=(l+r)>>1;
        	build(lson);
        	build(rson);
        	push_up(rt);
        }
        void update(int l,int r,int rt,int l1,int r1,int x)
        {
        	if(l1<=l&&r<=r1)
        	{
        		tr[rt]+=(r-l+1)*x;
        		lazy[rt]+=x;
        		return;
        	}
        	int mid=(l+r)>>1;
        	push_down(l,r,rt);
        	if(l1<=mid)update(lson,l1,r1,x);
        	if(r1>mid)update(rson,l1,r1,x);
        	push_up(rt);
        }
        ll query(int l,int r,int rt,int l1,int r1)
        {
        	if(l1<=l&&r<=r1)
        		return tr[rt];
        	int mid=(l+r)>>1;
        	ll res=0;
        	push_down(l,r,rt);
        	if(l1<=mid)res+=query(lson,l1,r1);
        	if(r1>mid)res+=query(rson,l1,r1);
        	return res;
        }
        int main()
        {
        	int n;
        	scanf("%d",&n);
        	for(int i=1;i<=n;i++)
        		scanf("%lld",&a[i]);
        	build(1,n,1);
        	int T;
        	scanf("%d",&T);
        	while(T--)
        	{
        		int op,l,r;
        		scanf("%d%d%d",&op,&l,&r);
        		if(op==1)
        		{
        			int x;
        			scanf("%d",&x);
        			update(1,n,1,l,r,x);
        		}
        		else
        		{
        			printf("%lld\n",query(1,n,1,l,r));
        		}
        	}
        	return 0;
        }
        
        • -1
          @ 2023-10-26 19:08:24

          #include <bits/stdc++.h> #define int long long using namespace std; const int N = 100005 , SN = 1005;

          int n , m , a[ N ]; int lenb; int q[ N ] , st[ SN ] , ed[ SN ]; int sum[ SN ] , add[ SN ];

          void modify( int l , int r , int v ) { int lx = q[ l ] , rx = q[ r ];

          if( lx == rx )
          {
          	sum[ lx ] += v * ( r - l + 1 );
          	for( int i = l ; i <= r ; i ++ )
          		a[ i ] += v;
          	return;
          }
          
          sum[ lx ] += v * ( ed[ lx ] - l + 1 );
          for( int i = l ; i <= ed[ lx ] ; i ++ )
          	a[ i ] += v;
          
          for( int i = lx + 1 ; i <= rx - 1 ; i ++ )
          	add[ i ] += v;
          
          sum[ rx ] += v * ( r - st[ rx ] + 1 ); 
          for( int i = st[ rx ] ; i <= r ; i ++ ) 
          	a[ i ] += v;
          

          }

          int query( int l , int r ) { int lx = q[ l ] , rx = q[ r ] , ans = 0;

          if( lx == rx )
          {
          	ans += add[ lx ] * ( r - l + 1 );
          	for( int i = l ; i <= r ; i ++ )
          		ans += a[ i ];
          	return ans;
          }
          
          ans += add[ lx ] * ( ed[ lx ] - l + 1 );
          for( int i = l ; i <= ed[ lx ] ; i ++ )
          	ans += a[ i ];
          
          for( int i = lx + 1 ; i <= rx - 1 ; i ++ )
          	ans += sum[ i ] + add[ i ] * lenb;
          
          ans += add[ rx ] * ( r - st[ rx ] + 1 ); 
          for( int i = st[ rx ] ; i <= r ; i ++ )
          	ans += a[ i ];
          
          return ans;
          

          }

          void init() { lenb = sqrt( n ); for( int i = 1 ; i <= ( n - 1 ) / lenb + 1 ; i ++ ) { st[ i ] = ( i - 1 ) * lenb + 1; ed[ i ] = min( i * lenb , n ); for( int j = st[ i ] ; j <= ed[ i ] ; j ++ ) q[ j ] = i , sum[ i ] += a[ j ]; } }

          signed main() { cin >> n; for( int i = 1 ; i <= n ; i ++ ) scanf( "%lld" , a + i ); init();

          cin >> m;
          while( m -- )
          {
          	int opt , l , r , v;
          	scanf( "%lld%lld%lld" , & opt , & l , & r );
          	
          	if( opt == 1 )
          	{
          		scanf( "%lld" , & v );
          		modify( l , r , v );
          	}
          	
          	if( opt == 2 )
          	{
          		printf( "%lld\n" , query( l , r ) );
          	}
          }
          
          return 0;
          

          }

          • 1

          信息

          ID
          3
          时间
          1000ms
          内存
          256MiB
          难度
          9
          标签
          递交数
          17
          已通过
          4
          上传者