标签:des http os io for 问题 代码 amp
http://acm.hdu.edu.cn/showproblem.php?pid=4893
开始的时候,我按双标记,WA了一下午,搞不定,我是用的两个标记add--表示当前结点中有值发生变化,flag,斐波那契的懒惰标记,但是估计是我自己处理的有问题,一直不对
参考了别人的代码,写法还是很不错的,Add变量维护的是,完全变成Fibonacci的时候的和,---回头我再重新写一遍
#include <cstdio> #include <cstring> #include <algorithm> #include <string> #include <iostream> #include <cmath> #include <map> #include <queue> using namespace std; #define ls(rt) rt*2 #define rs(rt) rt*2+1 #define ll long long #define rep(i,s,e) for(int i=s;i<e;i++) #define repe(i,s,e) for(int i=s;i<=e;i++) #define CL(a,b) memset(a,b,sizeof(a)) #define IN(s) freopen(s,"r",stdin) #define OUT(s) freopen(s,"w",stdin) const int MAXN =100000+100; ll ff[105]; ll num[MAXN]; void init() { ff[0]=ff[1]=1; for(int i=2;i<105;i++) ff[i]=ff[i-1]+ff[i-2]; } ll cal(ll x) { if(x == 0)return 1; int idx=lower_bound(ff,ff+105,x)-ff; //if(ff[idx] == x || idx==0)return ff[idx];// if(x-ff[idx-1]<=ff[idx]-x)return ff[idx-1]; else return ff[idx]; } struct Node{ int l,r; ll sum; ll add;//区间内某个值被改过,如果进行FF操作,需要将当前结点dfs int flag;//1,区间内有值变过/初始的时候,如果有fi区间更新的话需要重新更新 0--已经更新过程斐波那契,不需要更新 }nodes[MAXN*4]; void build(int rt, int l, int r) { nodes[rt].l=l; nodes[rt].r=r; nodes[rt].sum=0; nodes[rt].add=1;//没有做过fi修改 nodes[rt].flag=0; if(l==r) { num[l]=0; return; } int mid=(l+r)/2; build(ls(rt),l,mid); build(rs(rt),mid+1,r); if(nodes[rt].l==nodes[rt].r)return; nodes[rt].sum=nodes[ls(rt)].sum+nodes[rs(rt)].sum; nodes[rt].add=nodes[ls(rt)].add+nodes[rs(rt)].add; } /*void dfs(int rt) { if(0 == nodes[rt].flag)return;//已经修改过斐波那契 if(0 == nodes[rt].add)return;//区间内值没有做过修改 nodes[rt].flag=0;//改过 nodes[rt].add=0; if(nodes[rt].l == nodes[rt].r) { nodes[rt].sum=num[nodes[rt].l]=cal(num[nodes[rt].l]); return; } dfs(ls(rt)); dfs(rs(rt)); nodes[rt].sum=nodes[ls(rt)].sum+nodes[rs(rt)].sum; }*/ void pushdown(int rt) { if(nodes[rt].flag && nodes[rt].l==nodes[rt].r) { nodes[rt].sum=nodes[rt].add; nodes[rt].flag=0; return; } if(nodes[rt].flag) { nodes[ls(rt)].flag=nodes[rs(rt)].flag=1; nodes[ls(rt)].sum=nodes[ls(rt)].add; nodes[rs(rt)].sum=nodes[rs(rt)].add; nodes[rt].flag=0; } } void modify(int rt, int p, ll v) { if(nodes[rt].l==nodes[rt].r) { nodes[rt].sum+=v; nodes[rt].add=cal(nodes[rt].sum); num[nodes[rt].l]+=v; nodes[rt].flag=0; return; } pushdown(rt); //nodes[rt].add=1;//该节点的区间被修改过值,如果进行FF,需要dfs int mid=(nodes[rt].l+nodes[rt].r)/2; if(p<=mid)modify(ls(rt),p,v); else modify(rs(rt),p,v); if(nodes[rt].l==nodes[rt].r)return; nodes[rt].sum=nodes[ls(rt)].sum+nodes[rs(rt)].sum; nodes[rt].add=nodes[ls(rt)].add+nodes[rs(rt)].add;///////// } void update(int rt, int l, int r) { if(nodes[rt].l==l && nodes[rt].r==r) { nodes[rt].flag=1; //需要修改 nodes[rt].sum=nodes[rt].add; return; } pushdown(rt); int mid=(nodes[rt].l+nodes[rt].r)/2; if(r<=mid)update(ls(rt),l,r); else { if(l>mid)update(rs(rt),l,r); else { update(ls(rt),l,mid); update(rs(rt),mid+1,r); } } if(nodes[rt].l==nodes[rt].r)return; nodes[rt].sum=nodes[ls(rt)].sum+nodes[rs(rt)].sum; nodes[rt].add=nodes[ls(rt)].add+nodes[rs(rt)].add; } ll query(int rt, int l, int r) { //if(nodes[rt].flag && nodes[rt].add)dfs(rt); if(nodes[rt].l == l && nodes[rt].r==r) { return nodes[rt].sum; } pushdown(rt); int mid=(nodes[rt].l+nodes[rt].r)/2; ll ret=0; if(r<=mid)ret= query(ls(rt),l,r); else { if(l>mid)ret= query(rs(rt),l,r); else { ret= query(ls(rt),l,mid)+query(rs(rt),mid+1,r); } } if(nodes[rt].l!=nodes[rt].r) { nodes[rt].sum=nodes[ls(rt)].sum+nodes[rs(rt)].sum; nodes[rt].add=nodes[ls(rt)].add+nodes[rs(rt)].add; } return ret; } int main() { //IN("hdu4893.txt"); int n,m,op,l,r; init(); while(~scanf("%d%d",&n,&m)) { build(1,1,n); while(m--) { scanf("%d",&op); scanf("%d%d",&l,&r); if(op == 1) { modify(1,l,r); } if(op == 3) { update(1,l,r); } if(op == 2) { printf("%I64d\n",query(1,l,r)); } } } return 0; }
hdu 4893 线段树 --- 也是两个变 类似双标记,布布扣,bubuko.com
标签:des http os io for 问题 代码 amp
原文地址:http://blog.csdn.net/u011026968/article/details/38443539