4 条题解
-
1
#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
线段树解法代码:
#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
线段树求区间和
#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
#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
- 上传者