loj 6281 6284 number of columns of the block entry # 5 # 8

 

Solution: operating only prescribing, it will become after a number of experienced several prescription 1. Violent evolution, flag [] flag whether the block is a full radicand.

 

Code:

#include<bits/stdc++.h>
using namespace std;
const int maxn=100005;
int n,block,cnt,flag[maxn];
long long sum[maxn],w[maxn];
int get(int x);
void update(int l,int r,int c);
long long check(int l,int r);
int main()
{
  int i,op,l,r,c;
  scanf("%d",&n);
  
  block=sqrt(n);
  if(n%block) cnt=n/block+1;
  else cnt=n/block;
  
  for(i=1;i<=n;i++) 
  {
    scanf("%lld",&w[i]);
    sum[get(i)]+=w[i];
  }
  
  for(i=0;i<n;i++)
   {
     scanf("%d%d%d%d",&op,&l,&r,&c);
     if(op==0) update(l,r,c);
     else printf("%lld\n",check(l,r));
   }
  system("pause");
  return 0;
}
int get(int x)
{return (x-1)/block+1;}
void update(int l,int r,int c)
{
  int pre,end,k;
  pre=get(l);end=get(r);
  if(pre==end) 
   {
     for(k=l;k<=r;k++) 
     {
       sum[get(k)]-=w[k];
       w[k]=sqrt(w[k]);
       sum[get(k)]+=w[k];
     }
   }
  else
   {
     for(k=l;k<=min(pre*block,n);k++) 
     {
       sum[get(k)]-=w[k];
       w[k]=sqrt(w[k]);
       sum[get(k)]+=w[k];
     }
     for(k=(end-1)*block+1;k<=r;k++) 
     {
       sum[get(k)]-=w[k];
       w[k]=sqrt(w[k]);
       sum[get(k)]+=w[k];
     }
     for(k=pre+1;k<end;k++) 
     {
        if(flag[k]) continue;
        else
        {
          flag[k]=1;
          for(int j=(k-1)*block+1;j<=k*block;j++)
           {
               sum[k]-=w[j];
               w[j]=sqrt(w[j]);
               sum[k]+=w[j];
               if(w[j]!=1) flag[k]=0;
           }
        }
     }
   }
}
long long check(int l,int r)
{
  long long ans=0;
  int pre,end,k,x;
  pre=get(l);end=get(r);
  if(pre==end) 
   { 
     for(k=l;k<=r;k++) 
       ans+=w[k];
   }
  else
   {
     for(k=l;k<=min(pre*block,n);k++) ans+=w[k];
     for(k=(end-1)*block+1;k<=r;k++) ans+=w[k];
     for(k=pre+1;k<end;k++) 
      {
        if(flag[k]) ans+=block;
        else ans+=sum[k];
      }
   }
  return ans;
}

 

 

 

 

题解:与数列分块入门5类似。若某块全为同一个值,则用flag[ ]标记,直接计算,反之,暴力统计。

 

代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn=100005;
int n,block,w[maxn],flag[maxn];
int get(int k)
{return (k-1)/block+1;}
void reset(int k);
int check(int l,int r,int c);
int main()
{
  fill(flag,flag+maxn,-1);
  int i,l,r,c;
  scanf("%d",&n);
  block=sqrt(n);
  for(i=1;i<=n;i++) scanf("%d",&w[i]);
  for(i=0;i<n;i++)
  {
    scanf("%d%d%d",&l,&r,&c);
    printf("%d\n",check(l,r,c));
  }
  system("pause");
  return 0;
}
void reset(int k)
{
  if(flag[k]==-1) return ;
  for(int i=(k-1)*block+1;i<=min(k*block,n);i++)
    w[i]=flag[k];
  flag[k]=-1;
}
int check(int l,int r,int c)
{
  int pre,end,k,ans=0;
  pre=get(l);end=get(r);
  reset(pre);
  if(pre==end)
   {
     for(k=l;k<=r;k++) 
     {
      if(w[k]==c) ans++;
      else w[k]=c;
     }
   }
   else
   {
     reset(end);
     for(k=l;k<=min(pre*block,n);k++) 
      {
        if(w[k]==c) ans++;
        else w[k]=c;
      }
     for(k=(end-1)*block+1;k<=r;k++) 
      {
        if(w[k]==c) ans++;
        else w[k]=c;
      }
     for(k=pre+1;k<end;k++) 
      {
        if(flag[k]!=-1)
         {
          if(flag[k]==c) ans+=block;
          else flag[k]=c;
         } 
        else
         {
           flag[k]=c;
           for(int i=(k-1)*block+1;i<=k*block;i++)
            {
             if(w[i]==c) ans++;
             else w[i]=c;
            }
         }
      }
   }
  return ans;
}

Guess you like

Origin www.cnblogs.com/VividBinGo/p/11305725.html