Link: http://acm.hdu.edu.cn/showproblem.php? PID = 1, 4893
Question: Here is a series of N numbers with an initial length of 0. There are three operations: first, add D to the number at the K position, and second, query interval [L, the sum of R]. The third is to change the value of [L, R] To the Fibonacci number closest to it.
At the beginning, I used the sum array to store the node values. The third operation was an Interval Update, but the Interval Update values were different. I found the lowest node for updating, decisive. Later, I thought about it. In fact, I can add another information on the node, that is, the value to be changed in the third operation next time. This value is worth updating every time I perform the first operation, the interval also stores the total value after the next change, so that the interval update can be performed in the third operation, which is time-saving. I am not used to writing with struct, so I have defined an array.
The sum array stores normal values. The fuck array stores the next Fibonacci value to be changed. The Col array only serves as a tag.
In fact, this is a simple single-point update and Interval Update. In combination, I still did too little work. I didn't add Pushdown to the single-point update and interval query, and Wa made two rounds.
#include<cstring>#include<string>#include<fstream>#include<iostream>#include<iomanip>#include<cstdio>#include<cctype>#include<algorithm>#include<queue>#include<map>#include<set>#include<vector>#include<stack>#include<ctime>#include<cstdlib>#include<functional>#include<cmath>using namespace std;#define PI acos(-1.0)#define MAXN 100100#define eps 1e-11#define INF 0x7FFFFFFF#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1long long sum[MAXN<<2];long long col[MAXN<<2];long long fuck[MAXN<<2];long long n,m;long long f[100];void pushup(long long rt){ sum[rt] = sum[rt<<1] + sum[rt<<1|1]; fuck[rt] = fuck[rt<<1] + fuck[rt<<1|1];}void pushdown(long long rt,long long m){ if(col[rt]){ col[rt<<1] = fuck[rt<<1]; col[rt<<1|1] = fuck[rt<<1|1]; sum[rt<<1] = fuck[rt<<1]; sum[rt<<1|1] = fuck[rt<<1|1]; col[rt] = 0; }}void build(long long l,long long r,long long rt){ col[rt] = 0; if(l==r){ sum[rt] = 0; fuck[rt] = 1; return ; } long long m = (l+r)>>1; build(lson); build(rson); pushup(rt);}void update(long long pos,long long add,long long l,long long r,long long rt){ if(l==r){ sum[rt] += add; long long p = lower_bound(f,f+90,sum[rt])-f; if(p-1>=0){ long long fp1 = f[p] - sum[rt]; if(fp1<0) fp1 = -fp1; long long fp2 = f[p-1] - sum[rt]; if(fp2<0) fp2 = -fp2; if(fp1>=fp2) fuck[rt] = f[p-1]; else fuck[rt] = f[p]; } else fuck[rt] = f[p]; return ; } pushdown(rt,r-l+1); long long m = (l+r)>>1; if(pos<=m) update(pos,add,lson); else update(pos,add,rson); pushup(rt);}void update2(long long L,long long R,long long l,long long r,long long rt){ if(L<=l&&r<=R){ col[rt] = fuck[rt]; sum[rt] = fuck[rt]; return ; } pushdown(rt,r-l+1); long long m = (l+r)>>1; if(L<=m) update2(L,R,lson); if(R>m) update2(L,R,rson); pushup(rt);}long long query(long long L,long long R,long long l,long long r,long long rt){ if(L<=l&&r<=R){ return sum[rt]; } pushdown(rt,rt-l+1); long long ans = 0; long long m = (l+r)>>1; if(L<=m) ans += query(L,R,lson); if(R>m) ans += query(L,R,rson); return ans;}int main(){ long long i,j,l,r,k,d,x; f[0] = 1; f[1] = 1; for(i=2;i<90;i++){ f[i] = f[i-1] + f[i-2]; } while(scanf("%I64d%I64d",&n,&m)!=EOF){ build(1,n,1); while(m--){ scanf("%I64d%I64d%I64d",&x,&l,&r); if(x==1){ update(l,r,1,n,1); } else if(x==2){ long long ans = query(l,r,1,n,1); printf("%I64d\n",ans); } else{ update2(l,r,1,n,1); } } } return 0;}