2 条题解

  • 0
    @ 2026-8-5 19:42:46
    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    const int N=2e5+10,M=1010,inf=1e11;
    int a[N],tag[M],n,B;
    void pushdown(int x)
    {
    	if(tag[x]==inf)return;
    	int bl=(x-1)*B+1,br=min(n,x*B);
    	for(int i=bl;i<=br;i++)a[i]=tag[x];
    	tag[x]=inf;
    }
    int upd(int l,int r,int x)
    {
    	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]==x),a[i]=x;
    	}
    	else
    	{
    		pushdown(bl);
    		for(int i=l;i<=bl*B;i++)
    			ans+=(a[i]==x),a[i]=x;
    		pushdown(br);
    		for(int i=(br-1)*B+1;i<=r;i++)
    			ans+=(a[i]==x),a[i]=x;
    		for(int i=bl+1;i<br;i++)
    		{
    			if(tag[i]!=inf)
    			{
    				if(tag[i]==x)
    					ans+=B;
    			}
    			else
    				for(int j=(i-1)*B+1;j<=i*B;j++)ans+=a[j]==x;
    			tag[i]=x;
    		}
    	}
    	return ans;
    }
    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++)tag[i]=inf;
    	for(int i=1;i<=n;i++)
    	{
    		int l,r,c;cin>>l>>r>>c;
    		cout<<upd(l,r,c)<<'\n';
    	}
    	return 0;
    }
    • 0
      @ 2026-7-27 20:34:41
      #include <bits/stdc++.h>
      #define int long long
      using namespace std;
      
      const int N = 1e5 + 10, sqrtN = 350, INF = 1e18;
      // 区间查询等于c的个数并全改为c
      // a[i]记录每个点的值,b[i]记录每个点i所在块;
      // tag[i]记录第i个块的统一标记,若为INF表示块内元素不完全相同
      // 每个块i的左端点L[i]、右端点R[i]
      int n, a[N], b[N], L[sqrtN], R[sqrtN], tag[sqrtN];
      
      void push_down(int x) { // 下传第x个块的标记
          if (tag[x] != INF) {
              for (int i = L[x]; i <= R[x]; i++)
                  a[i] = tag[x];
              tag[x] = INF;
          }
      }
      
      void update_tag(int x) { // 更新第x个块的统一标记
          bool same = true;
          for (int i = L[x] + 1; i <= R[x]; i++) {
              if (a[i] != a[L[x]]) {
                  same = false;
                  break;
              }
          }
          if (same) tag[x] = a[L[x]];
          else tag[x] = INF;
      }
      
      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];
          }
          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);
          }
          for (int i = 1; i <= cnt; i++) {
              tag[i] = INF;
              update_tag(i); // 初始化时检查每块是否全同
          }
          
          for (int i = 1; i <= n; i++) {
              int l, r, c;
              cin >> l >> r >> c;
              int ans = 0;
              if (b[l] == b[r]) { // 如果l和r在同一块内
                  push_down(b[l]);
                  for (int j = l; j <= r; j++) {
                      if (a[j] == c) ans++;
                      a[j] = c;
                  }
                  update_tag(b[l]);
              } else {
                  // 左零散块
                  push_down(b[l]);
                  for (int j = l; j <= R[b[l]]; j++) {
                      if (a[j] == c) ans++;
                      a[j] = c;
                  }
                  update_tag(b[l]);
                  
                  // 中间完整块
                  for (int j = b[l] + 1; j <= b[r] - 1; j++) {
                      if (tag[j] != INF) { // 块内全同
                          if (tag[j] == c) {
                              ans += R[j] - L[j] + 1;
                          } else {
                              tag[j] = c;
                          }
                      } else { // 块内不全同
                          for (int k = L[j]; k <= R[j]; k++) {
                              if (a[k] == c) ans++;
                              a[k] = c;
                          }
                          tag[j] = c; // 整个块都被改成了c,直接打上标记
                      }
                  }
                  
                  // 右零散块
                  push_down(b[r]);
                  for (int j = L[b[r]]; j <= r; j++) {
                      if (a[j] == c) ans++;
                      a[j] = c;
                  }
                  update_tag(b[r]);
              }
              cout << ans << '\n';
          }
          return 0;
      }
      
      • 1

      信息

      ID
      476
      时间
      500ms
      内存
      256MiB
      难度
      7
      标签
      递交数
      17
      已通过
      8
      上传者