标签:线段树
1 1 2 1 1 5 4 1 1 7 1 3 17 3 2 4 2 1 5
0 22
#include<iostream>
#include<stdio.h>
using namespace std;
struct tree
{
    int l,r,t;
    __int64 s,ts;
}ss[100010*3];
__int64 f[100]={1,1};
void setit(int l,int r,int d)
{
    ss[d].l=l;
    ss[d].r=r;
    ss[d].t=0;//判断子结点是否需要进行3号操作
    ss[d].s=0;//当前区间内的总和
    ss[d].ts=1;//当前区间进行3号操作的备用和
    if(l==r)
        return;
    setit(l,(l+r)/2,d*2);
    setit((l+r)/2+1,r,d*2+1);
    ss[d].ts=ss[d*2].ts+ss[d*2+1].ts;
}
__int64 doublekill(__int64 k)//查找与k最相近的Fibonacci
{
    int l=0,r=77,mid;
    __int64 x1,x2;
    while(l<=r)
    {
        mid=(l+r)/2;
        if(f[mid]==k)return f[mid];
        if(f[mid]<k)l=mid+1;
        else r=mid-1;
    }
    x1=f[l]-k;
    if(x1<0)x1=-x1;
    if(l>0)
    {
        x2=f[l-1]-k;
        if(x2<0)x2=-x2;
        if(x2<=x1)return f[l-1];
    }
    return f[l];
}
void insert1(__int64 e,int k,int d)//点更新
{
    int l,r,mid;
    l=ss[d].l;
    r=ss[d].r;
    mid=(l+r)/2;
    if(l==r)
    {
        if(ss[d].t)
        {
            ss[d].s=ss[d].ts; ss[d].t=0;
        }
        ss[d].s+=e; ss[d].ts=doublekill(ss[d].s);//同时更新备用
        return;
    }
    if(ss[d].t)//如果当前段需要进行3号操作
    {
        ss[d*2].t=1; ss[d*2+1].t=1; ss[d].t=0;
        ss[d*2].s=ss[d*2].ts;
        ss[d*2+1].s=ss[d*2+1].ts;
    }
    if(k>mid)insert1(e,k,d*2+1);
    else insert1(e,k,d*2);
    ss[d].s=ss[d*2].s+ss[d*2+1].s;
    ss[d].ts=ss[d*2].ts+ss[d*2+1].ts;
}
void insert2(int l,int r,int d)//区间进行3号操作
{
    int ll,rr,mid;
    ll=ss[d].l;
    rr=ss[d].r;
    mid=(ll+rr)/2;
    if(ll>=l&&rr<=r)
    {
        ss[d].s=ss[d].ts; ss[d].t=1;//子结点需要3号操作更新
        return;
    }
    if(ss[d].t)
    {
        ss[d*2].t=1; ss[d*2+1].t=1; ss[d].t=0;
        ss[d*2].s=ss[d*2].ts;
        ss[d*2+1].s=ss[d*2+1].ts;
    }
    if(l<=mid)insert2(l,r,d*2);
    if(r>mid)insert2(l,r,d*2+1);
     ss[d].s=ss[d*2].s+ss[d*2+1].s;
}
__int64 find(int l,int r,int d)//求和
{
    __int64 ll,rr,mid,s=0;
    ll=ss[d].l;
    rr=ss[d].r;
    mid=(ll+rr)/2;
    if(ll>=l&&rr<=r)
    {
        return ss[d].s;
    }
    if(ss[d].t)
    {
        ss[d*2].t=1; ss[d*2+1].t=1; ss[d].t=0;
        ss[d*2].s=ss[d*2].ts;
        ss[d*2+1].s=ss[d*2+1].ts;
    }
    if(l<=mid)s+=find(l,r,d*2);
    if(r>mid)s+=find(l,r,d*2+1);
    ss[d].s=ss[d*2].s+ss[d*2+1].s;
    return s;
}
int main (void)
{
    int n,m,i,j,k,l;
    __int64 d;
    for(i=2;i<78;i++)
    f[i]=f[i-1]+f[i-2];
    while(scanf("%d%d",&n,&m)>0)
    {
        setit(1,n,1);
        while(m--)
        {
            scanf("%d%d",&j,&k);
            if(j==1)
            {
                scanf("%I64d",&d);insert1(d,k,1);
            }
            else
            {
                scanf("%d",&l);
                if(j==2)printf("%I64d\n",find(k,l,1));
                else insert2(k,l,1);
            }
        }
    }
    return 0;
}
hdu4893Wow! Such Sequence! (线段树),布布扣,bubuko.com
hdu4893Wow! Such Sequence! (线段树)
标签:线段树
原文地址:http://blog.csdn.net/u010372095/article/details/38274027