1 1 2 1 1 5 4 1 1 7 1 3 17 3 2 4 2 1 5
0 22
题意不说了,很简单的线段树题目了,就是打标记改点求段,修改段时由于极限次数不多,直接暴力更新到点,
好久没写线段树了,错了好多次,写的好傻逼。
代码:
/* *********************************************** Author :rabbit Created Time :2014/8/4 14:58:15 File Name :11.cpp ************************************************ */ #pragma comment(linker, "/STACK:102400000,102400000") #include <stdio.h> #include <iostream> #include <algorithm> #include <sstream> #include <stdlib.h> #include <string.h> #include <limits.h> #include <string> #include <time.h> #include <math.h> #include <queue> #include <stack> #include <set> #include <map> using namespace std; #define INF 0x3f3f3f3f #define eps 1e-8 #define pi acos(-1.0) typedef long long ll; ll fib[100]; struct node{ ll l,r; ll sum,flag; }a[800300]; ll m,n; void pushup(ll t){ if(a[t].l==a[t].r)return; a[t].sum=a[2*t].sum+a[2*t+1].sum; a[t].flag=a[2*t].flag&a[2*t+1].flag; } void build(ll t,ll l,ll r){ // cout<<"hhh "<<l<<" "<<r<<endl; a[t].l=l; a[t].r=r; a[t].sum=a[t].flag=0; if(l==r)return; ll mid=(l+r)/2; build(2*t,l,mid); build(2*t+1,mid+1,r); pushup(t); } void update1(ll t,ll p,ll val){ if(a[t].l==a[t].r){ a[t].sum+=val; a[t].flag=0; return; } ll mid=(a[t].l+a[t].r)/2; if(p<=mid)update1(2*t,p,val); else update1(2*t+1,p,val); pushup(t); } ll Find(ll x){ if(x <= 1)return 1; int l = 1, r = 80, id = 80; while(l <= r){ int mid = l+r>>1; if(fib[mid] > x) id = mid, r = mid-1; else l = mid+1; } if(x-fib[id-1] <= fib[id]-x) return fib[id-1]; return fib[id]; } void update2(ll t,ll l,ll r){ if(a[t].flag)return; if(a[t].l==a[t].r){ a[t].sum=Find(a[t].sum); a[t].flag=1; //cout<<"ddd "<<l<<" "<<r<<" "<<a[t].sum<<endl; return; } ll mid=(a[t].l+a[t].r)/2; if(l<=mid)update2(2*t,l,r); if(r>mid)update2(2*t+1,l,r); pushup(t); } ll getsum(ll t,ll l,ll r){ if(a[t].l>=l&&a[t].r<=r)return a[t].sum; ll mid=(a[t].l+a[t].r)/2; ll ans=0; if(l<=mid)ans+=getsum(2*t,l,r); if(r> mid) ans+=getsum(2*t+1,l,r); return ans; } int main() { // freopen("data.in","r",stdin); // freopen("data.out","w",stdout); fib[0]=1;fib[1]=1; for(ll i=2;i<=90;i++)fib[i]=fib[i-1]+fib[i-2]; while(~scanf("%I64d%I64d",&n,&m)){ // cout<<"ddd "<<endl; build(1,1,n); //cout<<"ppp "<<endl; while(m--){ ll l,r,op; scanf("%I64d%I64d%I64d",&op,&l,&r); if(op==1){ update1(1,l,r); // cout<<"han 1"<<endl; } if(op==2){ printf("%I64d\n",getsum(1,l,r)); // cout<<"han 2"<<endl; } if(op==3){ update2(1,l,r); // cout<<"han 3"<<endl; } } } return 0; } /* 5 10 2 1 5 3 1 5 2 1 5 1 1 10 2 1 5 3 1 5 2 1 5 4 5 1 1 3 2 1 2 3 2 3 1 2 1 2 1 4 */
原文:http://blog.csdn.net/xianxingwuguan1/article/details/38374041