• 数据结构:分块-区间开方与区间求和


    在对整块儿进行开方操作的时候,因为块儿内每一个元素都有各自的特点,所以不好去统一维护

    这题的修改就只有下取整开方,而一个数经过几次开方之后,它的值就会变成 0 或者 1

    如果每次区间开方只不涉及完整的块,意味着不超过2√n个元素,直接暴力即可

    如果涉及了一些完整的块,这些块经过几次操作以后就会都变成 0 / 1

    只要每个整块暴力开方后,记录一下元素是否都变成了 0 / 1

    区间修改时跳过那些全为 0 / 1 的块即可

    这样每个元素至多被开方不超过4次

    这种优化就比较不显然了,但是很管用

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cmath>
     4 using namespace std;
     5 const int maxn=50005;
     6 int n,blo;
     7 int bl[maxn],v[maxn],sum[maxn],flag[maxn];
     8 long long read()
     9 {
    10     long long x=0,f=1;char ch=getchar();
    11     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    12     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    13     return x*f;
    14 }
    15 void solve_sqrt(int x)
    16 {
    17     if(flag[x]) return;
    18     flag[x]=1;
    19     sum[x]=0;
    20     for(int i=(x-1)*blo+1;i<=x*blo;i++)
    21     {
    22         v[i]=sqrt(v[i]),sum[x]+=v[i];
    23         if(v[i]>1) flag[x]=0;
    24     }
    25 }
    26 void add(int a,int b,int c)
    27 {
    28     for(int i=a;i<=min(bl[a]*blo,b);i++)
    29     {
    30         sum[bl[a]]-=v[i];
    31         v[i]=sqrt(v[i]);
    32         sum[bl[a]]+=v[i];
    33     }
    34     if(bl[a]!=bl[b])
    35         for(int i=(bl[b]-1)*blo+1;i<=b;i++)
    36         {
    37             sum[bl[b]]-=v[i];
    38             v[i]=sqrt(v[i]);
    39             sum[bl[b]]+=v[i];
    40         }
    41     for(int i=bl[a]+1;i<=bl[b]-1;i++)
    42         solve_sqrt(i);
    43 }
    44 int query(int a,int b)
    45 {
    46     int ans=0;
    47     for(int i=a;i<=min(bl[a]*blo,b);i++) ans+=v[i];
    48     if(bl[a]!=bl[b])
    49         for(int i=(bl[b]-1)*blo+1;i<=b;i++) ans+=v[i];
    50     for(int i=bl[a]+1;i<=bl[b]-1;i++) ans+=sum[i];
    51     return ans;
    52 }
    53 int main()
    54 {
    55     n=read();blo=sqrt(n);
    56     for(int i=1;i<=n;i++) v[i]=read();
    57     for(int i=1;i<=n;i++)
    58     {
    59         bl[i]=(i-1)/blo+1;
    60         sum[bl[i]]+=v[i];
    61     }
    62     for(int i=1;i<=n;i++)
    63     {
    64         int f=read(),a=read(),b=read(),c=read();
    65         if(f==0) add(a,b,c);
    66         if(f==1) printf("%d
    ",query(a,b));
    67     }
    68 }

    分块儿不仅简单而且骚操作啊

  • 相关阅读:
    Mix 10 上的asp.net mvc 2的相关Session
    Vista、XP SP2主流支持即将终止
    向Visual Studio 2010迁移的电子书
    ASP.NET MVC 2 转换工具
    Javascript瘦身工具AJAX Minifier
    微软公司的安全开发周期模型
    User Experience Kit
    乐在其中设计模式(C#) 迭代器模式(Iterator Pattern)
    [翻译]使用ASP.NET AJAX让GridView的数据行显示提示框(ToolTip)
    [翻译]使用ASP.NET AJAX实现幻灯片效果
  • 原文地址:https://www.cnblogs.com/aininot260/p/9525702.html
Copyright © 2020-2023  润新知