2 条题解

  • 0
    @ 2026-8-9 9:46:17
    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    const int N=1e6+10,M=1010;
    int a[N],s1[N],s2[N],tag[N],n,B;
    void pushdown(int x)
    {
    	int bl=(x-1)*B+1,br=min(x*B,n);
    	for(int i=bl;i<=br;i++)a[i]=a[i]+tag[x];
    	tag[x]=0;
    }
    void upd(int l,int r,int x)
    {
    	int bl=(l-1)/B+1,br=(r-1)/B+1;
    	if(bl==br)
    	{
    		pushdown(bl);
    		for(int i=l;i<=r;i++)
    		{
    			s1[bl]-=a[i]*a[i];
    			a[i]+=x;s2[bl]+=x;
    			s1[bl]+=a[i]*a[i];
    		}
    	}
    	else
    	{
    		pushdown(bl);
    		for(int i=l;i<=bl*B;i++)
    		{
    			s1[bl]-=a[i]*a[i];
    			a[i]+=x;s2[bl]+=x;
    			s1[bl]+=a[i]*a[i];
    		}
    		pushdown(br);
    		for(int i=(br-1)*B+1;i<=r;i++)
    		{
    			s1[br]-=a[i]*a[i];
    			a[i]+=x;s2[br]+=x;
    			s1[br]+=a[i]*a[i];
    		}
    		for(int i=bl+1;i<br;i++)
    		{
    			s1[i]+=2*x*s2[i]+B*x*x;
    			s2[i]+=B*x;
    			tag[i]+=x;
    		}
    	}
    }
    int query(int l,int r)
    {
    	int bl=(l-1)/B+1,br=(r-1)/B+1,ans=0;
    	if(bl==br)
    	{
    		pushdown(bl);
    		for(int i=l;i<=r;i++)ans+=a[i]*a[i];
    	}
    	else
    	{
    		pushdown(bl);
    		for(int i=l;i<=bl*B;i++)ans+=a[i]*a[i];
    		pushdown(br);
    		for(int i=(br-1)*B+1;i<=r;i++)ans+=a[i]*a[i];
    		for(int i=bl+1;i<br;i++)ans+=s1[i];
    	}
    	return ans;
    }
    signed main()
    {
    	int q;cin>>n>>q;B=sqrt(n);
    	for(int i=1;i<=n;i++)
    	{
    		cin>>a[i];
    		s1[(i-1)/B+1]+=a[i]*a[i];
    		s2[(i-1)/B+1]+=a[i];
    	}
    	while(q--)
    	{
    		int op,l,r,c;cin>>op>>l>>r;
    		if(op==0)cin>>c,upd(l,r,c);
    		else cout<<query(l,r)<<'\n';
    	}
    	return 0;
    }
    • 0
      @ 2026-7-7 2:01:24
      #include <bits/stdc++.h>
      #define int long long
      using namespace std;
      
      const int N = 1e6 + 10, sqrtN = 1050;
      // 区间加,区间求平方和
      // a[i]记录每个点的值,b[i]记录每个点i所在块;
      // sum1[i]记录第i个块的一次方和,sum2[i]记录第i个块的平方和
      // 每个块i的左端点L[i]、右端点R[i], 块内标记tag[i]
      int n, m, a[N], b[N], L[sqrtN], R[sqrtN], tag[sqrtN], sum1[sqrtN], sum2[sqrtN];
      
      void push_down(int x) { // 下传第x个块的标记
          if (tag[x]) {
              for (int i = L[x]; i <= R[x]; i++)
                  a[i] += tag[x];
              tag[x] = 0;
          }
      }
      
      void calc(int x) { // 重新计算第x个块的sum1和sum2
          sum1[x] = 0;
          sum2[x] = 0;
          for (int i = L[x]; i <= R[x]; i++) {
              sum1[x] += a[i];
              sum2[x] += a[i] * a[i];
          }
      }
      
      signed main() {
          ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
          cin >> n >> m;
          for (int i = 1; i <= n; i++) {
              cin >> a[i];
          }
          int B = sqrt(n), cnt = (n + B - 1) / B; // B为每块的长度,cnt为总块数
          for (int i = 1; i <= n; i++) b[i] = (i - 1) / B + 1;
          for (int i = 1; i <= cnt; i++) {
              L[i] = (i - 1) * B + 1;
              R[i] = min(i * B, n);
              calc(i);
          }
          memset(tag, 0, sizeof(tag));
          for (int i = 1; i <= m; i++) {
              int op, l, r, c;
              cin >> op >> l >> r;
              if (op == 0) {
                  cin >> c;
                  if (b[l] == b[r]) { // 如果l和r在同一块内
                      push_down(b[l]);
                      for (int j = l; j <= r; j++) a[j] += c;
                      calc(b[l]);
                  } else {
                      push_down(b[l]);
                      for (int j = l; j <= R[b[l]]; j++) a[j] += c;
                      calc(b[l]);
      
                      for (int j = b[l] + 1; j <= b[r] - 1; j++) {
                          sum2[j] += 2 * c * sum1[j] + (R[j] - L[j] + 1) * c * c;
                          sum1[j] += (R[j] - L[j] + 1) * c;
                          tag[j] += c;
                      }
      
                      push_down(b[r]);
                      for (int j = L[b[r]]; j <= r; j++) a[j] += c;
                      calc(b[r]);
                  }
              } else {
                  int ans = 0;
                  if (b[l] == b[r]) { // 如果l和r在同一块内
                      for (int j = l; j <= r; j++) {
                          int val = a[j] + tag[b[l]];
                          ans += val * val;
                      }
                  } else {
                      for (int j = l; j <= R[b[l]]; j++) {
                          int val = a[j] + tag[b[l]];
                          ans += val * val;
                      }
                      for (int j = b[l] + 1; j <= b[r] - 1; j++) {
                          ans += sum2[j];
                      }
                      for (int j = L[b[r]]; j <= r; j++) {
                          int val = a[j] + tag[b[r]];
                          ans += val * val;
                      }
                  }
                  cout << ans << '\n';
              }
          }
          return 0;
      }
      
      • 1

      信息

      ID
      478
      时间
      3000ms
      内存
      128MiB
      难度
      7
      标签
      递交数
      29
      已通过
      9
      上传者