2014 Multi-University Training Contest 3 1007 && HDU 4893 Wow! Such Sequence ! (线段树)

来源:互联网 发布:魅族系统升级数据清理 编辑:程序博客网 时间:2024/05/21 06:59

题目链接:HDU 4893 Wow! Such Sequence !

用线段树比较明显,其中一个更新是将一个区间中的每个值变成和他最近的斐波那契数,这里有个小技巧。就是第一次变化后如再次询问,最近斐波那契数就是其本身,所以不需要再次更新。



AC代码:


#include<stdio.h>#include<set>#define int64 __int64#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1using namespace std;int64 f[10000];const int maxn=200000;set<int64> ss;struct node{    int64 l,r,laz;    int64 sum;    int64 mid()    {        return (l+r)/2;    }};struct node tree[maxn<<2];void getf()//斐波那契打表。{    int i;    f[0]=1,f[1]=1;    ss.insert(f[0]);    ss.insert(f[1]);    for(i=2;i<=73;i++)    {        f[i]=f[i-1]+f[i-2];        ss.insert(f[i]);    }}void PushUp(int64 rt){if(tree[rt<<1].laz && tree[rt<<1|1].laz) //将标记向上推tree[rt].laz=1;elsetree[rt].laz=0;tree[rt].sum=tree[rt<<1].sum+tree[rt<<1|1].sum;}void build(int64 l,int64 r,int64 rt){    tree[rt].l=l;    tree[rt].r=r;    tree[rt].laz=0;    if(tree[rt].l==tree[rt].r)    {        tree[rt].sum=0;        return ;    }    int64 m=tree[rt].mid();    build(lson);    build(rson);PushUp(rt);}void updata(int64 p,int64 add,int64 rt){    if(tree[rt].l==tree[rt].r)    {        tree[rt].laz=0;//加过后标记更新        tree[rt].sum+=add;        return ;    }    int64 m=tree[rt].mid();        if(p<=m)        updata(p,add,rt<<1);    else        updata(p,add,rt<<1|1);PushUp(rt);}void updata2(int64 L,int64 R,int64 rt){if(tree[rt].laz==1) //其子节点都被更新过。return ;    if(tree[rt].l==tree[rt].r)    {        tree[rt].laz=1;        int64 l,r;        set<int64>::iterator it1,it2;        it2=it1=ss.lower_bound(tree[rt].sum);        l=*it2;        if(it1!=ss.begin())            it1--;        r=*it1;        tree[rt].sum=(tree[rt].sum-*it1)> ((*it2)-tree[rt].sum)?l:r;        return ;    }    int64 m=tree[rt].mid();        if(R<=m)        updata2(L,R,rt<<1);    else if(L>m)        updata2(L,R,rt<<1|1);else{updata2(L,R,rt<<1);updata2(L,R,rt<<1|1);}PushUp(rt);}int64 query(int64 L,int64 R,int64 rt){    if(L<=tree[rt].l && tree[rt].r<=R)    {        return tree[rt].sum;    }    int64 m=tree[rt].mid();    int64 ret=0;    if(R<=m)        ret+=query(L,R,rt<<1);    else if(L>m)        ret+=query(L,R,rt<<1|1);    else    {        ret+=query(L,R,rt<<1);        ret+=query(L,R,rt<<1|1);    }    return ret;}int main(){    int64 a,b,c;    int64 op,i;    int64 n,m;    ss.clear();    getf();    while(scanf("%I64d %I64d",&n,&m)!=EOF)    {        build(1,n,1);        while(m--)        {            scanf("%I64d",&op);            if(op==2)            {                scanf("%I64d %I64d",&a,&b);                printf("%I64d\n",query(a,b,1));            }            else if(op==1)            {                scanf("%I64d %I64d",&a,&b);                updata(a,b,1);            }            else if(op==3)//f            {                scanf("%I64d %I64d",&a,&b);                updata2(a,b,1);            }        }    }return 0;}


1 0
原创粉丝点击