数列分块入门 5(及区间开方,区间求和)

题目链接:https://loj.ac/problem/6281

题目大意:中文题目

具体思路:具体的优化就是判断当期你的区间如果为1或者0的话,再开根就没有变化了,这样就不需要开根了,判断每一个块是否需要开根。

AC代码:

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 # define ll long long
  4 const int maxn =  2e6+100;
  5 const int inf = 0x3f3f3f3f;
  6 ll l[maxn],r[maxn],belong[maxn];
  7 ll add[maxn],a[maxn],sum[maxn];
  8 bool flag[maxn];
  9 int n;
 10 void buildblock()
 11 {
 12     ll tmp=(ll)sqrt(n);
 13     ll tot=n/tmp;
 14     if(n%tmp)
 15         tot++;
 16     for(ll i=1; i<=n; i++)
 17     {
 18         belong[i]=(i-1)/tmp+1ll;
 19     }
 20     for(ll  i=1; i<=tot; i++)
 21     {
 22         l[i]=(i-1)*tmp+1ll;
 23         r[i]=i*tmp;
 24     }
 25     r[tot]=n;
 26     for(int i=1; i<=tot; i++)
 27     {
 28         for(int j=l[i]; j<=r[i]; j++)
 29         {
 30             sum[i]+=a[j];
 31         }
 32     }
 33 }
 34 void update(ll st,ll ed)
 35 {
 36     if(belong[st]==belong[ed])
 37     {
 38         if(!flag[belong[st]])
 39             return ;
 40         for(int i=st; i<=ed; i++)
 41         {
 42             a[i]=(int)sqrt(a[i]);
 43         }
 44         flag[belong[st]]=0;
 45         sum[belong[st]]=0;
 46         for(int i=l[belong[st]]; i<=r[belong[st]]; i++)
 47         {
 48             sum[belong[st]]+=a[i];
 49             if(a[i]>1)
 50                 flag[belong[st]]=1;
 51         }
 52         return ;
 53     }
 54     for(int i=st; i<=r[belong[st]]; i++)
 55     {
 56         a[i]=(int)sqrt(a[i]);
 57     }
 58     flag[belong[st]]=0;
 59     sum[belong[st]]=0;
 60     for(int i=l[belong[st]]; i<=r[belong[st]]; i++)
 61     {
 62         sum[belong[st]]+=a[i];
 63         if(a[i]>1)
 64             flag[belong[st]]=1;
 65     }
 66     for(int i=l[belong[ed]]; i<=ed; i++)
 67     {
 68         a[i]=(int)sqrt(a[i]);
 69     }
 70     flag[belong[ed]]=0;
 71     sum[belong[ed]]=0;
 72     for(int i=l[belong[ed]]; i<=r[belong[ed]]; i++)
 73     {
 74         sum[belong[ed]]+=a[i];
 75         if(a[i]>1)
 76             flag[belong[ed]]=1;
 77     }
 78     for(int i=belong[st]+1; i<belong[ed]; i++)
 79     {
 80             if(!flag[i])
 81             continue;
 82         flag[i]=0;
 83         sum[i]=0;
 84         for(int j=l[i]; j<=r[i]; j++)
 85         {
 86             a[j]=(int)sqrt(a[j]);
 87             sum[i]+=a[j];
 88             if(a[j]>1)
 89                 flag[i]=1;
 90         }
 91     }
 92 }
 93 ll ask(ll st,ll ed)
 94 {
 95     ll ans=0;
 96     if(belong[st]==belong[ed])
 97     {
 98         for(int i=st; i<=ed; i++)
 99         {
100             ans+=a[i];
101         }
102         return ans;
103     }
104     for(int i=st; i<=r[belong[st]]; i++)
105     {
106         ans+=a[i];
107     }
108     for(int i=l[belong[ed]]; i<=ed; i++)
109     {
110         ans+=a[i];
111     }
112     for(int i=belong[st]+1; i<belong[ed]; i++)
113     {
114         ans+=sum[i];
115     }
116     return ans;
117 }
118 int main()
119 {
120     memset(flag,1,sizeof(flag));
121     scanf("%d",&n);
122     for(int i=1; i<=n; i++)
123     {
124         scanf("%lld",&a[i]);
125     }
126     buildblock();
127     ll op,st,ed;
128     ll val;
129     while(n--)
130     {
131         scanf("%lld %lld %lld %lld",&op,&st,&ed,&val);
132         if(op==0)
133         {
134             update(st,ed);
135         }
136         else
137         {
138             printf("%lld
",ask(st,ed));
139         }
140     }
141     return 0;
142 }

 

原文地址:https://www.cnblogs.com/letlifestop/p/10470677.html