2 条题解

  • 0
    @ 2026-8-5 19:14:32

    分块新技能 +1+1

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e5+10,M=1010,P=10007;
    int a[N],tag1[M],tag2[M],n,B;
    void pushdown(int x)
    {
    	int bl=(x-1)*B+1,br=min(n,x*B);
    	for(int i=bl;i<=br;i++)a[i]=(a[i]*tag2[x]+tag1[x])%P;
    	tag1[x]=0,tag2[x]=1;
    }
    void upd1(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++)
    			a[i]=(a[i]+x)%P;
    	}
    	else
    	{
    		pushdown(bl);pushdown(br);
    		for(int i=l;i<=bl*B;i++)a[i]=(a[i]+x)%P;
    		for(int i=(br-1)*B+1;i<=r;i++)a[i]=(a[i]+x)%P;
    		for(int i=bl+1;i<br;i++)tag1[i]=(tag1[i]+x)%P;
    	} 
    }
    void upd2(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++)
    			a[i]=a[i]*x%P;
    	}
    	else
    	{
    		pushdown(bl);pushdown(br);
    		for(int i=l;i<=bl*B;i++)a[i]=a[i]*x%P;
    		for(int i=(br-1)*B+1;i<=r;i++)a[i]=a[i]*x%P;
    		for(int i=bl+1;i<br;i++)
    		{
    			tag1[i]=tag1[i]*x%P;
    			tag2[i]=tag2[i]*x%P;
    		}
    	}
    }
    signed main()
    {
    	cin>>n;B=sqrt(n);
    	for(int i=1;i<=n;i++)cin>>a[i];
    	for(int i=1;i<=(n-1)/B+1;i++)tag2[i]=1;
    	for(int i=1;i<=n;i++)
    	{
    		int op,l,r,c;cin>>op>>l>>r>>c;
    		if(op==0)upd1(l,r,c);
    		if(op==1)upd2(l,r,c);
    		if(op==2)pushdown((r-1)/B+1),cout<<a[r]<<"\n";
    	}
    	return 0;
    }
    • 0
      @ 2026-7-27 20:29:26
      #include <bits/stdc++.h>
      #define int long long
      using namespace std;
      
      const int N = 1e5 + 10, sqrtN = 350, MOD = 10007;
      // 区间加法,区间乘法,单点查询
      // a[i]记录每个点的值,b[i]记录每个点i所在块;
      // add_tag[i]记录第i个块的加法标记,mul_tag[i]记录第i个块的乘法标记
      // 每个块i的左端点L[i]、右端点R[i]
      int n, a[N], b[N], L[sqrtN], R[sqrtN], add_tag[sqrtN], mul_tag[sqrtN];
      
      void push_down(int x) { // 下传第x个块的标记
          for (int i = L[x]; i <= R[x]; i++) {
              a[i] = (a[i] * mul_tag[x] + add_tag[x]) % MOD;
          }
          mul_tag[x] = 1;
          add_tag[x] = 0;
      }
      
      signed main() {
          ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
          cin >> n;
          for (int i = 1; i <= n; i++) {
              cin >> a[i];
              a[i] %= MOD;
          }
          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);
          }
          memset(add_tag, 0, sizeof(add_tag));
          for (int i = 1; i <= cnt; i++) mul_tag[i] = 1;
          for (int i = 1; i <= n; i++) {
              int op, l, r, c;
              cin >> op >> l >> r >> c;
              if (op == 0) { // 区间加
                  if (b[l] == b[r]) { // 如果l和r在同一块内
                      push_down(b[l]);
                      for (int j = l; j <= r; j++)
                          a[j] = (a[j] + c) % MOD;
                  } else {
                      push_down(b[l]);
                      for (int j = l; j <= R[b[l]]; j++)
                          a[j] = (a[j] + c) % MOD;
                      for (int j = b[l] + 1; j <= b[r] - 1; j++)
                          add_tag[j] = (add_tag[j] + c) % MOD;
                      push_down(b[r]);
                      for (int j = L[b[r]]; j <= r; j++)
                          a[j] = (a[j] + c) % MOD;
                  }
              } else if (op == 1) { // 区间乘
                  if (b[l] == b[r]) { // 如果l和r在同一块内
                      push_down(b[l]);
                      for (int j = l; j <= r; j++)
                          a[j] = (a[j] * c) % MOD;
                  } else {
                      push_down(b[l]);
                      for (int j = l; j <= R[b[l]]; j++)
                          a[j] = (a[j] * c) % MOD;
                      for (int j = b[l] + 1; j <= b[r] - 1; j++) {
                          mul_tag[j] = (mul_tag[j] * c) % MOD;
                          add_tag[j] = (add_tag[j] * c) % MOD;
                      }
                      push_down(b[r]);
                      for (int j = L[b[r]]; j <= r; j++)
                          a[j] = (a[j] * c) % MOD;
                  }
              } else { // 单点查询
                  cout << (a[r] * mul_tag[b[r]] + add_tag[b[r]]) % MOD << '\n';
              }
          }
          return 0;
      }
      
      • 1

      信息

      ID
      475
      时间
      500ms
      内存
      256MiB
      难度
      5
      标签
      递交数
      23
      已通过
      12
      上传者