codeforces 446 c

题目的大意是你需要维护一个序列a,有两种操作:

1.对于区间[l,r],对于l<=i<=r,ai+=f[i-l+1],f是斐波那契数列

2.查询区间[l,r]的和

很久以前在培训的时候写过,然而并不会做,后来一直拖到退役也没有搞懂,今天心血来潮研究了一下,发现还是比较简单的。

很明显,这道题我们需要用线段树来维护,因为有区间操作,所以我们需要打标记,但是我们知道,线段树的标记应该满足可传递性,显然直接打标记是错误的

我们进行一个推倒:

设a,b是斐波那契数列中连续的两项,那么之后的序列应该是这样的:

a , b , a+b , a+2b , 2a+3b , 3a+5b...

我们发现从第三项开始a的系数是1,1,2,3,5

b的系数是1,2,3,5

也就是说其后的第i项应该是:a*f[i-2]+b*f[i-1]

那么我们对其后的n项求一个和,那么就应该是:a*(f[1]+f[2]+f[3]+...+f[n-2])+b*(f[1]+f[2]+f[3]+...+f[n-1])

那么我们发现想要维护一个区间[l,r]的标记我们只需要维护a和b即可,其后的取决于区间的长度

比如我们标记了[l,r]

那当我们下传标记的时候应该怎么做呢?

[l,(l+r)>>1] 的a和b直接下传即可

[(l+r)>>1|1,r]的a和b就要变化了,因为这里的(l+r)>>1|1实际上是[l,r]的第(l+r)>>1|1-l+1项,所以a就是(l+r)>>1|1-l+1,b是a+1

这样就可以做到下标的传递了,每次标记直接相加即可。

这道题也就解决了,代码过几天再写。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstdlib>
  4 #include<cstring>
  5 #include<string>
  6 #include<algorithm>
  7 #define mod 1000000009
  8 #define ll long long
  9 using namespace std;
 10 struct tree{
 11     int l,r;
 12     ll taga,tagb;
 13     ll sum;
 14 }f[1200005];
 15 int n,m;
 16 ll fib[300005],a[300005],sf[300005];
 17 void update(int i,int ta,int tb){
 18     int len=f[i].r-f[i].l+1;
 19     //cout<<f[i].sum<<endl;
 20     if(len>=2){
 21         ll tmp1=(ta*sf[len-2])%mod,tmp2=(tb*sf[len-1])%mod;
 22         tmp1=(tmp1+tmp2)%mod;
 23         //cout<<tmp1<<endl;
 24         f[i].sum=(f[i].sum+tmp1)%mod;
 25         f[i].sum=(f[i].sum+ta)%mod;
 26     }
 27     else{
 28         f[i].sum=(f[i].sum+ta)%mod;
 29         f[i].sum=(f[i].sum+tb*(len-1))%mod;
 30     }
 31     //cout<<f[i].sum<<endl;
 32     f[i].taga=(f[i].taga+ta)%mod;
 33     f[i].tagb=(f[i].tagb+tb)%mod;
 34     return ;
 35 }
 36 void pushup(int i){
 37     f[i].sum=(f[i<<1].sum+f[i<<1|1].sum)%mod;
 38     return ;
 39 }
 40 void pushdown(int i){
 41     if(f[i].taga){
 42         update(i<<1,f[i].taga,f[i].tagb);
 43         int mid=(f[i].r+f[i].l)>>1,len=(mid-f[i].l+1);
 44         //if(len>=2){
 45             ll tmp1=((f[i].taga*fib[len-1])%mod+(f[i].tagb*fib[len])%mod)%mod;
 46             ll tmp2=((f[i].taga*fib[len])%mod+(f[i].tagb*fib[len+1])%mod)%mod;
 47             update(i<<1|1,tmp1%mod,tmp2%mod);
 48        // }
 49         //else update(i<<1|1,f[i].tagb,(f[i].taga+f[i].tagb)%mod);
 50         f[i].taga=0;f[i].tagb=0;
 51         return ;
 52     }
 53     else return ;
 54 }
 55 void build(int i,int left,int right){
 56     f[i].l=left;f[i].r=right;
 57     if(left==right){
 58         f[i].sum=a[left];
 59         return ;
 60     }
 61     int mid=(left+right)>>1;
 62     build(i<<1,left,mid);build(i<<1|1,mid+1,right);
 63     pushup(i);
 64     //cout<<f[i].sum<<f[i<<1].sum<<f[i<<1|1].sum<<endl;
 65     return ;
 66 }
 67 void add(int i,int left,int right,int num){
 68     if(f[i].l==left&&f[i].r==right){
 69         update(i,fib[num],fib[num+1]);
 70         return ;
 71     }
 72     pushdown(i);
 73     int mid=f[i<<1].r,len=(mid-left+1);
 74     if(right<=mid)add(i<<1,left,right,num);
 75     else if(left>mid)add(i<<1|1,left,right,num);
 76     else add(i<<1,left,mid,num),add(i<<1|1,mid+1,right,num+len);
 77     pushup(i);
 78 }
 79 ll query(int i,int left,int right){
 80     if(f[i].l==left&&f[i].r==right)return f[i].sum;
 81     pushdown(i);
 82     int mid=(f[i].l+f[i].r)>>1;
 83     if(right<=mid)return query(i<<1,left,right);
 84     else if(mid<left)return query(i<<1|1,left,right);
 85     else return (query(i<<1,left,mid)+query(i<<1|1,mid+1,right))%mod;
 86 }
 87 int main(){
 88     //freopen("input.txt","r",stdin);
 89     fib[1]=1;fib[2]=1;sf[1]=1;sf[2]=2;
 90     ios_base::sync_with_stdio(false);
 91     cin.tie(0);
 92     cin>>n>>m;
 93     for(int i=1;i<=n;i++)
 94         cin>>a[i];
 95     for(int i=3;i<=n+3;i++){
 96         fib[i]=(fib[i-1]+fib[i-2])%mod;
 97         sf[i]=(sf[i-1]+fib[i])%mod;
 98     }
 99     build(1,1,n);
100     for(int i=1;i<=m;i++){
101         int x,y,z;
102         cin>>x>>y>>z;
103          //cout<<"SSS"<<endl;
104         if(x==1)add(1,y,z,1);
105         else cout<<query(1,y,z)<<'\n';
106          //cout<<"SSS"<<endl;
107     }
108     return 0;
109 }
View Code

 

转载于:https://www.cnblogs.com/htwx/articles/7624561.html

### Codeforces Problem 1332C Explanation The provided references pertain specifically to problem 742B on Codeforces rather than problem 1332C. For an accurate understanding and solution approach for problem 1332C, it's essential to refer directly to its description and constraints. However, based on general knowledge regarding competitive programming problems found on platforms like Codeforces: Problem 1332C typically involves algorithmic challenges that require efficient data structures or algorithms such as dynamic programming, graph theory, greedy algorithms, etc., depending upon the specific nature of the task described within this particular question[^6]. To provide a detailed explanation or demonstration concerning **Codeforces problem 1332C**, one would need direct access to the exact statement associated with this challenge since different tasks demand tailored strategies addressing their unique requirements. For obtaining precise details about problem 1332C including any sample inputs/outputs along with explanations or solutions, visiting the official Codeforces website and navigating to contest number 1332 followed by examining section C is recommended. ```python # Example pseudo-code structure often seen in solving competitive coding questions. def solve_problem_1332C(input_data): # Placeholder function body; actual logic depends heavily on the specifics of problem 1332C. processed_result = process_input(input_data) final_answer = compute_solution(processed_result) return final_answer input_example = "Example Input" print(solve_problem_1332C(input_example)) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值