【2014 Multi-University Training Contest 3 1007】/【HDU 4893】 Wow! Such Sequence!

来源:互联网 发布:购买域名送空间 编辑:程序博客网 时间:2024/05/16 04:45

第三场了,还是只有一道题能在赛后补出来。

题目大意:

给出n个数,初始值为0.有三种操作:

1.将某一个数加d。

2.询问区间[l,r]之间的数总和。

3,将区间[l,r]之间的数变成与其距离最近的斐波那契数,若两边距离相同则选择小的。



解题思路:

线段树

对于第一种操作使用点更新,对于第三种操作使用区间更新。


居然上首页了o(∩_∩)o !!

























下面是代码:

#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <set>#include <map>#include <string>#include <math.h>#include <stdlib.h>#define clear(A, X, SIZE) memset(A, X, sizeof(A[0]) * (SIZE))#define clearall(A, X) memset(A, X, sizeof(A))#define max( x, y )  ( ((x) > (y)) ? (x) : (y) )#define min( x, y )  ( ((x) < (y)) ? (x) : (y) )using namespace std;struct node1{    long long nsum,fsum;    int sta,l,r,m; //all none -1 all f 1} node[100000<<2];long long f[100];void build(int l,int r,int tr){    node[tr].nsum=0;    node[tr].fsum=1;    node[tr].sta=-1;    node[tr].l=l;    node[tr].r=r;    node[tr].m=(l+r)>>1;    if(l==r)return;    int m=(l+r)>>1;    build(l,m,tr<<1);    build(m+1,r,tr<<1|1);    node[tr].fsum=node[tr<<1].fsum+node[tr<<1|1].fsum;}void update1(int p,long long num,int tr){    if(node[tr].l==node[tr].r&&node[tr].l==p)    {        if(node[tr].sta==1)node[tr].nsum=node[tr].fsum;        node[tr].nsum+=num;        int l=2,r=90,i;        while(l<r)        {            i=(l+r)>>1;            if(f[i]>node[tr].nsum)r=i;            else l=i+1;        }        i=r;        if(f[i]-node[tr].nsum<node[tr].nsum-f[i-1])node[tr].fsum=f[i];        else node[tr].fsum=f[i-1];        node[tr].sta=-1;        return;    }    if(node[tr].sta==1)    {        node[tr<<1].sta=1;        node[tr<<1|1].sta=1;    }    if(p>=node[tr].l&&p<=node[tr].m)update1(p,num,tr<<1);    else if(node[tr].m<p&&p<=node[tr].r)update1(p,num,tr<<1|1);    node[tr].nsum=node[tr<<1].nsum+node[tr<<1|1].nsum;    node[tr].fsum=node[tr<<1].fsum+node[tr<<1|1].fsum;    if(node[tr<<1].sta+node[tr<<1|1].sta==-2)node[tr].sta=-1;    else if(node[tr<<1].sta+node[tr<<1|1].sta==2)node[tr].sta=1;    else node[tr].sta=0;}void update(int L,int R,int tr){    if(node[tr].sta==1)    {        return ;    }    if(L<=node[tr].l&&node[tr].r<=R)    {        node[tr].sta=1;        return ;    }    if(L<=node[tr].m)update(L,R,tr<<1);    if(node[tr].m<R)update(L,R,tr<<1|1);    if(node[tr<<1].sta+node[tr<<1|1].sta==-2)node[tr].sta=-1;    else if(node[tr<<1].sta+node[tr<<1|1].sta==2)node[tr].sta=1;    else node[tr].sta=0;}long long query(int L,int R,int tr){    if(L<=node[tr].l&&node[tr].r<=R&&node[tr].sta==-1)return node[tr].nsum;    else if(L<=node[tr].l&&node[tr].r<=R&&node[tr].sta==1)return node[tr].fsum;    if(node[tr].sta==1)    {        node[tr<<1].sta=1;        node[tr<<1|1].sta=1;    }    long long ans=0;    if(L<=node[tr].m)ans+=query(L,R,tr<<1);    if(node[tr].m<R)ans+=query(L,R,tr<<1|1);    if(node[tr<<1].sta+node[tr<<1|1].sta==-2)node[tr].sta=-1;    else if(node[tr<<1].sta+node[tr<<1|1].sta==2)node[tr].sta=1;    else node[tr].sta=0;    return ans;}int main(){    int n,m;    f[1]=1;    f[2]=1;    for(int i=3; i<93; i++)    {        f[i]=f[i-1]+f[i-2];    }    int x,l,r;    long long tt;    while(scanf("%d%d",&n,&m)!=EOF)    {        build(1,n,1);        for(int i=0; i<m; i++)        {            scanf("%d",&x);            if(x==1)            {                scanf("%d%I64d",&l,&tt);                update1(l,tt,1);            }            else if(x==2)            {                scanf("%d%d",&l,&r);                printf("%I64d\n",query(l,r,1));            }            else            {                scanf("%d%d",&l,&r);                update(l,r,1);            }        }    }    return 0;}


0 0