【BZOJ】3038 上帝造题的七分钟2

【算法】线段树||(坑...)

【题解】修改必须暴力单点修改,然后利用标记区间查询。

优化:一个数经过不断开方很快就会变成1,所以维护区间最大值。

修改时访问到的子树最大值<=1时,该区间就不必修改。

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn=100010;
struct treess{int k,l,r;long long maxs,sum;}t[maxn*3];
int n,m;long long a[maxn];
void build(int k,int l,int r)
{
    t[k].l=l;t[k].r=r;
    if(l==r)t[k].maxs=t[k].sum=a[l];
     else
      {
          int mid=(l+r)>>1;
          build(k<<1,l,mid);
          build(k<<1|1,mid+1,r);
          t[k].maxs=max(t[k<<1].maxs,t[k<<1|1].maxs);//printf("k=%d maxs=%d",k,t[k].maxs);
          t[k].sum=t[k<<1].sum+t[k<<1|1].sum;
      }
}
void update(int k,int l,int r)
{
    int left=t[k].l,right=t[k].r;
    if(t[k].maxs<=1)return;
    if(left==right)a[left]=floor(sqrt(a[left])),t[k].maxs=t[k].sum=a[left];
     else
      {
          int mid=(left+right)>>1;
          if(l<=mid)update(k<<1,l,r);
          if(r>mid)update(k<<1|1,l,r);
          t[k].maxs=max(t[k<<1].maxs,t[k<<1|1].maxs);
          t[k].sum=t[k<<1].sum+t[k<<1|1].sum;
      }
}
long long ask(int k,int l,int r)
{
    int left=t[k].l,right=t[k].r;
    if(l<=left&&right<=r)return t[k].sum;
    int mid=(left+right)>>1;long long ans=0;
    if(l<=mid)ans=ask(k<<1,l,r);
    if(r>mid)ans+=ask(k<<1|1,l,r);
    return ans;
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
    scanf("%d",&m);
    build(1,1,n);
    for(int i=1;i<=m;i++)
     {
         int k,l,r;
         scanf("%d%d%d",&k,&l,&r);
         if(l>r)swap(l,r);
         if(k==0)update(1,l,r);
          else printf("%lld\n",ask(1,l,r));
     }
    return 0;
}

BZOJ 3211 花神游历各国 树状数组+并查集

时间: 2024-11-07 02:08:15

【BZOJ】3038 上帝造题的七分钟2的相关文章

BZOJ 3038 上帝造题的七分钟2 (并查集+树状数组)

题解:同 BZOJ 3211 花神游历各国,需要注意的是需要开long long,还有左右节点需要注意一下. #include <cstdio> #include <cmath> #include <iostream> #include <algorithm> using namespace std; typedef long long LL; LL a[100005],c[100005]; int f[100005],n,m,op,l,r,t; int s

bzoj 3038: 上帝造题的七分钟2 线段树||hdu 4027

3038: 上帝造题的七分钟2 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 1066  Solved: 476[Submit][Status][Discuss] Description XLk觉得<上帝造题的七分钟>不太过瘾,于是有了第二部."第一分钟,X说,要有数列,于是便给定了一个正整数数列.第二分钟,L说,要能修改,于是便有了对一段数中每个数都开平方(下取整)的操作.第三分钟,k说,要能查询,于是便有了求一段数的和的操作.第四分

BZOJ 3038: 上帝造题的七分钟2【线段树区间开方问题】

3038: 上帝造题的七分钟2 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 1469  Solved: 631[Submit][Status][Discuss] Description XLk觉得<上帝造题的七分钟>不太过瘾,于是有了第二部. "第一分钟,X说,要有数列,于是便给定了一个正整数数列. 第二分钟,L说,要能修改,于是便有了对一段数中每个数都开平方(下取整)的操作. 第三分钟,k说,要能查询,于是便有了求一段数的和的操作.

BZOJ 3038 上帝造题的七分钟2 树状数组+并查集

题目大意:一个序列,有两种操作,1.将一段数中的每一个数开根号.2.查询一段数的和. 思路:和3211是一个题,有兴趣的可以看看我的那篇博客. CODE: #include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 100010 using namespace std; int cnt,asks

BZOJ 3038 上帝造题的七分钟2

我们发现每个数被开平方的次数不是太多. 然后1开平方还是1. 然后怎么办? 暴力啊!只要找到没有1的地方暴力做就可以了. #include<iostream>#include<cstdio>#include<cstring>#include<cmath>#define maxn 100500using namespace std;long long ls[maxn<<3],rs[maxn<<3],value[maxn<<3

3038: 上帝造题的七分钟2 [线段树 暴力]

3038: 上帝造题的七分钟2 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 1210  Solved: 536[Submit][Status][Discuss] Description XLk觉得<上帝造题的七分钟>不太过瘾,于是有了第二部."第一分钟,X说,要有数列,于是便给定了一个正整数数列.第二分钟,L说,要能修改,于是便有了对一段数中每个数都开平方(下取整)的操作.第三分钟,k说,要能查询,于是便有了求一段数的和的操作.第四分

3038: 上帝造题的七分钟2

3038: 上帝造题的七分钟2 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 662  Solved: 302[Submit][Status] Description XLk觉得<上帝造题的七分钟>不太过瘾,于是有了第二部."第一分钟,X说,要有数列,于是便给定了一个正整数数列.第二分钟,L说,要能修改,于是便有了对一段数中每个数都开平方(下取整)的操作.第三分钟,k说,要能查询,于是便有了求一段数的和的操作.第四分钟,彩虹喵说,要是n

BZOJ 3132: 上帝造题的七分钟( 二维BIT )

二维树状数组... 自己YY一下再推一下应该可以搞出来... ---------------------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #define rep( i , n ) for( int i = 0 ; i <

[BZOJ 3038]上帝造题的7分钟2(树状数组)

分析:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3038 这题看起来没办法做……但是注意到1e12只要开方8次就能到1……所以直接暴力就行了……