您的位置:首页 > 产品设计 > UI/UE

hdu 4893 Wow! Such Sequence! (线段树 区间更新+单点更新)

2015-08-03 21:22 441 查看
/*
1 k d 第k个数加d
2 l r 查询l到r的和
3 l r l到r更新到最近的f[]
*/
# include <stdio.h>
# include <algorithm>
# include <string.h>
using namespace std;
# define lson l,m,rt<<1
# define rson m+1,r,rt<<1|1
# define N 100005
__int64 sum[N<<2],need[N<<2],L[N<<2],R[N<<2];
__int64 f[110];
int col[N<<2];
__int64 find(__int64 x)//二分查找最近f[]
{
if(x<=1)
return 1;
int left=1;
int right=93;
while(left<=right)
{
int mid=(left+right)>>1;
if(f[mid]-x>0)
right=mid-1;
else
left=mid+1;
}
// printf("%I64d %I64d\n",f[left],f[left-1]);
//int left=lower_bound(f,f+93,x)-f;
if(f[left]-x>=x-f[left-1])
return f[left-1];
return f[left];
}
void PushUP(int rt)
{
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
need[rt]=need[rt<<1]+need[rt<<1|1];
}
void PushDown(int rt)
{
if(col[rt]!=-1)
{
col[rt<<1]=col[rt<<1|1]=1;
sum[rt<<1]+=need[rt<<1];
sum[rt<<1|1]+=need[rt<<1|1];
need[rt<<1|1]=need[rt<<1]=0;
col[rt]=-1;
}
}
void build(int l,int r,int rt)
{
col[rt]=-1;
sum[rt]=0;
if(l==r)
{
need[rt]=1;//如果没有更新过 原来是0所以最小需要1到底f[]
return ;
}
int m=(l+r)>>1;
build(lson);
build(rson);
PushUP(rt);
}
void add(int a,int val,int l,int r,int rt)//单点更新
{
if(l==r)
{
sum[rt]+=val;
col[rt]=1;
need[rt]=find(sum[rt])-sum[rt];
return ;
}
PushDown(rt);
int m=(l+r)>>1;
if(a<=m)
add(a,val,lson);
else
add(a,val,rson);
PushUP(rt);
}
void update(int a,int b,int l,int r,int rt)//区间更新为最近且最小的斐波那契数
{
if(a<=l&&b>=r)
{
sum[rt]+=need[rt];
col[rt]=1;
need[rt]=0;
return ;
}
PushDown(rt);
int m=(l+r)>>1;
if(a<=m)
update(a,b,lson);
if(b>m)
update(a,b,rson);
PushUP(rt);
}
__int64 query(int a,int b,int l,int r,int rt)
{
if(a<=l&&b>=r)
{
return sum[rt];
}
PushDown(rt);
__int64 ret=0;
int m=(l+r)>>1;
if(a<=m)
ret+=query(a,b,lson);
if(b>m)
ret+=query(a,b,rson);
return ret;
}
int main()
{
f[0]=1;
f[1]=1;
for(int i=2; i<=93; i++)
{
f[i]=f[i-1]+f[i-2];
}
int n,m,op,b,c;
while(~scanf("%d%d",&n,&m))
{
build(1,n,1);
while(m--)
{
scanf("%d%d%d",&op,&b,&c);
if(op==1)
{
add(b,c,1,n,1);
}
else if(op==2)
{
printf("%I64d\n",query(b,c,1,n,1));
}
else
{
update(b,c,1,n,1);
}

}
// for(int i=1; i<=n; i++)
//    printf("%I64d\n",query(i,i,1,n,1));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: