hdu 4893 线段树+二分fib
来源:互联网 发布:淘宝强行退款 编辑:程序博客网 时间:2024/05/16 10:43
http://acm.hdu.edu.cn/showproblem.php?pid=4893
这道题题意很清楚~就是线段树的运用,其中的第三个操作,也就是将一个数转变为与这个数相邻最小fib数;
如果直接操作,因为操作次数很多,应该会TLE,我们可以在每个树节点上加个cover变量,如果等于1,那么表示这个区间里的数已经是fib数了,不需要再更改了,这样就避免时间的浪费;
标准模板转自:http://blog.csdn.net/u011932355/article/details/38276763;
表示,自己敲不是RE,就是TLE,比赛的时候RE了一下午;无解了;
#include <stdio.h>
#include <string.h>
#include <cmath>
#include <iostream>
typedef long long ll;
using namespace std;
const int maxn=55;
struct node
{
int l,r,cover;
__int64 sum;
}data[400010];
__int64 a[maxn+1];
__int64 find_near(__int64 x) //二分找fib数
{
int l,r,mid;
l=1; r=maxn;
if (x<0) return 1;
while (l<=r)
{
mid=(l+r)/2;
if (a[mid]==x) return a[mid];
if (a[mid]<x) l=mid+1;
else r=mid-1;
}
if (x-a[l-1]<=a[l]-x) return a[l-1];
else return a[l];
}
void build(int l,int r,int k)
{
int mid;
data[k].l=l;
data[k].r=r;
data[k].sum=0;
data[k].cover=0;
if (l==r) return ;
mid=(l+r)/2;
build(l,mid,k*2);
build(mid+1,r,k*2+1);
}
void updata(int n,int x,int k)
{
int mid;
if (data[k].l==n && data[k].r==n)
{
data[k].sum+=x;
if (data[k].sum==find_near(data[k].sum)) data[k].cover=1;
else data[k].cover=-1;
return ;
}
mid=(data[k].l+data[k].r)/2;
if (n<=mid) updata(n,x,k*2);
else updata(n,x,k*2+1);
data[k].sum=data[k*2].sum+data[k*2+1].sum;
if (data[k*2].cover==data[k*2+1].cover) data[k].cover=data[k*2].cover;
else data[k].cover=-1;
}
__int64 search(int l,int r,int k)
{
int mid;
if (data[k].l==l && data[k].r==r)
return data[k].sum;
mid=(data[k].l+data[k].r)/2;
if (r<=mid) return search(l,r,k*2);
else if (l>mid) return search(l,r,k*2+1);
else return search(l,mid,k*2)+search(mid+1,r,k*2+1);
}
void change(int l,int r,int k)
{
int mid;
if (data[k].cover==1) return ;
if (data[k].l==data[k].r)
{
data[k].sum=find_near(data[k].sum);
data[k].cover=1;
return ;
}
mid=(data[k].l+data[k].r)/2;
if(r<=mid) change(l,r,k*2);
else if (l>mid) change(l,r,k*2+1);
else {change(l,mid,k*2); change(mid+1,r,k*2+1);}
data[k].sum=data[k*2].sum+data[k*2+1].sum;
if (data[k*2].cover==data[k*2+1].cover) data[k].cover=data[k*2].cover;
else data[k].cover=0;
}
int main()
{
int n,m,op,b,c,i;
a[0]=a[1]=1;
for (i=2;i<=maxn;i++)
a[i]=a[i-1]+a[i-2];
while (scanf("%d%d",&n,&m)!=EOF)
{
build(1,n,1);
while (m--)
{
scanf("%d%d%d",&op,&b,&c);
if (op==1) updata(b,c,1);
if (op==2) printf("%I64d\n",search(b,c,1));
if (op==3) change(b,c,1);
}
}
return 0;
}
- hdu 4893 线段树+二分fib
- HDU 4893(Wow! Such Sequence!-线段树单点修改+区间求和+改为最近Fib数)
- hdu 4339 线段树+二分
- hdu 4614 线段树+二分~
- HDU 4614 线段树+二分
- HDU 4791二分+线段树
- HDU - 4973(线段树+二分)
- hdu 4339 线段树+二分
- hdu 4614 线段树+二分
- hdu 5592 线段树 + 二分
- HDU 3450 线段树+二分
- hdu 4614 线段树+二分
- HDU 5649 (二分 线段树)
- HDU 6070 二分+线段树
- hdu 6070二分+线段树
- HDU 4614 线段树+二分
- HDU 5649 线段树+二分
- hdu 4737 线段树维护+二分
- poj 1258 Agri-Net(最小生成树,普里姆算法)
- ios--MBProgressHUD(使用方式一)--在事件的执行过程中显示+指定显示时间长短
- TIANKENG’s restaurant
- Gray Code
- ArcGis for android 加载tpk离线文件(http://blog.csdn.net/vpingchangxin/article/details/8778869)
- hdu 4893 线段树+二分fib
- Spring AOP(面向切面编程)【Spring AOP的技术基础】
- 分享:APK高级保护方法解析(一)
- 关于二进制补码
- 把字符串转换为整数
- Business Rules(From Wiki)
- java.util.RandomAccessSubList cannot be cast to java.util.ArrayList解决办法
- 山东理工OJ【2117】数据结构实验之链表二:逆序建立链表
- 分析碳素钢与合金钢的区别是什么?