码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2017-07-13 15:58:57      阅读:172      评论:0      收藏:0      [点我收藏+]

标签:for   line   span   inline   nbsp   getchar   cst   pac   string   

根据一个数六次√必死,我们可以打标记死了就不管他了,于是有贡献的操作复杂度为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 线段树

标签:for   line   span   inline   nbsp   getchar   cst   pac   string   

原文地址:http://www.cnblogs.com/TSHugh/p/7160255.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!