线段树:
三种操作:1.将第k位的数加上d
2.求区间l,r所有数之和
3.将区间l,r内所有数变为最近的Fibonacci数
维护两个变量,第一个是区间内所有数之和sum,第二个如果区间内所有数变为 Fibonacci数 sum的改变量num
我的代码:
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
long long sum[300000],num[300000];
bool yes[300000];
long long Fib[1000];
long long Fibo(){
Fib[0]=Fib[1]=1;
for (int i=2;i<92;i++) {
Fib[i]=Fib[i-1]+Fib[i-2];
}
return 0;
}
long long MaxCF(long long x){
//cout<<"x="<<x<<endl;
if (x<=1) return 1;
if (x>=Fib[91]) return Fib[91];
for (int i=1;i<=91;i++){
if (x>=Fib[i]&&x<=Fib[i+1]) {
if (x-Fib[i]>Fib[i+1]-x) return Fib[i+1];
else return Fib[i];
}
}
}
int build (int o,int L,int R){
yes[o]=false;
int M=L+(R-L)/2;
if (L==R) sum[o]=0,num[o]=1;
else {
build(o*2,L,M);
build(o*2+1,M+1,R);
sum[o]=sum[o*2]+sum[o*2+1];
num[o]=num[o*2]+num[o*2+1];
}
return 0;
}
int maintain(int o,int L,int R){
int lc=o*2,rc=o*2+1;
//sum[o]=0;
//num[o]=0;
if (R>L) {
sum[o]=sum[lc]+sum[rc];
num[o]=num[o*2]+num[o*2+1];
}
return 0;
}
long long k,d;
int pushdown(int o,int L,int R){
int lc=o*2,rc=o*2+1;
if (yes[o]){
if (L<R){
yes[lc]=true;
yes[rc]=true;
sum[lc]+=num[lc];
num[lc]=0;
sum[rc]+=num[rc];
num[rc]=0;
}
yes[o]=false;
}
return 0;
}
long long _sum,y1,y2;
int query(int o,int L,int R){
if (yes[o]) pushdown(o,L,R);
if (y1<=L&&y2>=R){
_sum+=sum[o];
}
else {
int M=L+(R-L)/2;
if (y1<=M) query(o*2,L,M);
if (y2>M) query(o*2+1,M+1,R);
}
return 0;
}
int add(int o,int L,int R){
if (yes[o]) pushdown(o,L,R);
if (L==R&&L==k){
sum[o]+=d;
num[o]=MaxCF(sum[o])-sum[o];
}
else {
int M=L+(R-L)/2;
if (k<=M) add(o*2,L,M);
if (k>M) add(o*2+1,M+1,R);
maintain(o,L,R);
}
return 0;
}
int setF(int o,int L,int R){
if (yes[o]) return 0;
if (y1<=L&&y2>=R) {
yes[o]=true;
sum[o]+=num[o];
num[o]=0;
}
else {
int M=L+(R-L)/2;
if (y1<=M) setF(o*2,L,M);
if (y2>M) setF(o*2+1,M+1,R);
maintain(o,L,R);
}
return 0;
}
int main (){
Fibo();
int n,m;
while (~scanf("%d%d",&n,&m)){
build (1,1,n);
for (int i=0;i<m;i++){
// cout<<"IIIII"<<endl;
int a,b,c;cin>>a>>b>>c;
if (a==1){
k=b;d=c;
add(1,1,n);
}
if (a==3){
y1=b;y2=c;
setF(1,1,n);
}
if (a==2){
y1=b;y2=c;
_sum=0;
query(1,1,n);
cout<<_sum<<endl;
}
}
}
return 0;
}