BZOJ3038上帝造题的七分钟2 线段树

Posted TS_Hugh

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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\n",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;
}

 

以上是关于BZOJ3038上帝造题的七分钟2 线段树的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ_3038_上帝造题的七分钟2_线段树

BZOJ3038上帝造题的七分钟2 线段树

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

BZOJ3038 上帝造题的七分钟2

BZOJ3038: 上帝造题的七分钟2

BZOJ3038: 上帝造题的七分钟2