zoukankan      html  css  js  c++  java
  • 【BZOJ3038】上帝造题的七分钟2 线段树

    根据一个数六次√必死,我们可以打标记死了就不管他了,于是有贡献的操作复杂度为O(n*logn*6),然而我们还有由于盲目修改造成的多余代价我们把每次查询的区间分成三部分前全死,中残,后全死,对于中残,我们的操作都是由于为了有价值的操作而操作的,(无论中间残的那里面断断续续的死的是多长,他的向下都是为了做出贡献),而两边的多余费用最多O(4*logn),最终约为O(10*n*logn)

    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<iostream>
    #define MAXN 100005
    using namespace std;
    typedef long long LL;
    inline LL read_LL()
    {
        LL sum=0;
        char ch=getchar();
        while(ch<'0'||ch>'9')ch=getchar();
        while(ch>='0'&&ch<='9')
        {
            sum=(sum<<1)+(sum<<3)+ch-'0';
            ch=getchar();
        }
        return sum;
    }
    inline int read()
    {
        int sum=0;
        char ch=getchar();
        while(ch<'0'||ch>'9')ch=getchar();
        while(ch>='0'&&ch<='9')
        {
            sum=(sum<<1)+(sum<<3)+ch-'0';
            ch=getchar();
        }
        return sum;
    }
    struct Seg_Tree
    {
        Seg_Tree *ch[2];
        int over,l,r,mid;
        LL sum;
    }S[MAXN<<2],*root;
    LL key[MAXN];
    int n,m;
    int sz;
    inline Seg_Tree *New(int l,int r)
    {
        Seg_Tree *p=S+sz;
        sz++;
        p->l=l;
        p->r=r;
        p->mid=(l+r)>>1;
        return p;
    }
    inline void pushup(Seg_Tree *p)
    {
        if(p->l==p->r)
        {
          p->sum=key[p->mid];
          if(p->sum==1)
           p->over=1;
          return;
        }
        p->sum=p->ch[0]->sum+p->ch[1]->sum;
        if(p->ch[0]->over&&p->ch[1]->over)
         p->over=1;
    }
    void build(Seg_Tree *p)
    {
        if(p->l==p->r)
        {
            pushup(p);
            return;
        }
        p->ch[0]=New(p->l,p->mid);
        build(p->ch[0]);
        p->ch[1]=New(p->mid+1,p->r);
        build(p->ch[1]);
        pushup(p);
    }
    inline void Init()
    {
        n=read();
        for(int i=1;i<=n;i++)
         key[i]=read_LL();
        root=New(1,n);
        build(root);
    }
    void pushdown(Seg_Tree *p,int l,int r)
    {
        if(p->over)return;
        if(p->l==p->r)
        {
            key[p->mid]=(LL)(sqrt(key[p->mid]+0.5));
            pushup(p);
            return;
        }
        if(p->mid>=l)
         pushdown(p->ch[0],l,r);
        if(p->mid<r)
         pushdown(p->ch[1],l,r);
        pushup(p);
    }
    LL query(Seg_Tree *p,int l,int r)
    {
        if(l<=p->l&&p->r<=r)
         return p->sum;
        LL ans=0;
        if(l<=p->mid)
         ans+=query(p->ch[0],l,r);
        if(p->mid<r)
         ans+=query(p->ch[1],l,r);
        return ans;
    }
    inline void work()
    {
        m=read();
        while(m--)
        {
            int opt=read(),x=read(),y=read();
            if(x>y)x^=y^=x^=y;
            if(opt) printf("%lld
    ",query(root,x,y));
            else pushdown(root,x,y);
        }
    }
    int main()
    { 
       freopen("god.in","r",stdin);
       freopen("god.out","w",stdout);
       Init();
       work();
       return 0;
    }
  • 相关阅读:
    MVC3 中上传大文件
    js 将十进制转换为八位二进制数组
    nodejs 读取并处理二进制文件
    freeswitch源码编译 ./configure 遇到的问题
    通道设置静态坐席
    呼叫中心静态座席的配置
    ECharts报表
    combotree
    openlayer PanZoom
    为什么要始终使用PreparedStatement代替Statement?
  • 原文地址:https://www.cnblogs.com/TSHugh/p/7160255.html
Copyright © 2011-2022 走看看