zoukankan      html  css  js  c++  java
  • BZOJ3211: 花神游历各国

    【传送门:BZOJ3211


    简要题意:

      给出一个序列,对这些序列进行两种操作:

      1 x y求出x到y的和

      2 x y将x到y的数全部开方(向下取整)


    题解:

      线段树+面向数据编程

      线段树显然不可以整体开方,所以必须要一个一个开,一般来说是超时的

      但是因为每个数不超过109,所以每个数最多只会开5次方,最终会成为0或1,而开方0或1是没有任何意义的

      所以我们只要在0或1的地方打个标记,然后就可以避免问到多余的叶子节点

      要加long long


    参考代码:

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    typedef long long LL;
    struct node
    {
        int l,r,lc,rc;LL c;
        bool lazy;
    }tr[210000];int trlen;
    LL a[110000];
    void bt(int l,int r)
    {
        trlen++;int now=trlen;
        tr[now].l=l;tr[now].r=r;tr[now].c=0;
        tr[now].lc=tr[now].rc=-1;tr[now].lazy=false;
        if(l==r)
        {
            tr[now].c=a[l];
            if(tr[now].c==1||tr[now].c==0) tr[now].lazy=true;
        }
        else
        {
            int mid=(l+r)/2;
            tr[now].lc=trlen+1;bt(l,mid);
            tr[now].rc=trlen+1;bt(mid+1,r);
            tr[now].c=tr[tr[now].lc].c+tr[tr[now].rc].c;
            if(tr[tr[now].lc].lazy==true&&tr[tr[now].rc].lazy==true) tr[now].lazy=true;
        }
    }
    LL getsum(int now,int l,int r)
    {
        if(tr[now].l==l&&tr[now].r==r) return tr[now].c;
        int lc=tr[now].lc,rc=tr[now].rc,mid=(tr[now].l+tr[now].r)/2;
        if(r<=mid) return getsum(lc,l,r);
        else if(l>mid) return getsum(rc,l,r);
        else return getsum(lc,l,mid)+getsum(rc,mid+1,r);
    }
    void change(int now,int l,int r)
    {
        if(tr[now].lazy==true) return ;
        if(tr[now].l==tr[now].r)
        {
            tr[now].c=LL(sqrt(tr[now].c));
            if(tr[now].c==1||tr[now].c==0) tr[now].lazy=true;
            return ;
        }
        int lc=tr[now].lc,rc=tr[now].rc,mid=(tr[now].l+tr[now].r)/2;
        if(r<=mid) change(lc,l,r);
        else if(l>mid) change(rc,l,r);
        else
        {
            change(lc,l,mid);
            change(rc,mid+1,r);
        }
        tr[now].c=tr[lc].c+tr[rc].c;
        if(tr[lc].lazy==true&&tr[rc].lazy==true) tr[now].lazy=true;
    }
    int main()
    {
        int n,m;
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
        trlen=0;bt(1,n);
        scanf("%d",&m);
        for(int i=1;i<=m;i++)
        {
            int t,x,y;
            scanf("%d%d%d",&t,&x,&y);
            if(x>y) swap(x,y);
            if(t==1) printf("%lld
    ",getsum(1,x,y));
            else change(1,x,y);
        }
        return 0;
    }

     

  • 相关阅读:
    js对象数组(JSON) 根据某个共同字段 分组
    一个 函数 用来转化esSearch 的range 条件
    关于 vuex 报错 Do not mutate vuex store state outside mutation handlers.
    android listview 重用view导致的选择混乱问题
    android SDK和ADT的更新
    Android中adb push和adb install的使用区别
    pycharm中添加扩展工具pylint
    su Authentication failure解决
    Putty以及adb网络调试
    有关android源码编译的几个问题
  • 原文地址:https://www.cnblogs.com/Never-mind/p/8524866.html
Copyright © 2011-2022 走看看