日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

整数序列(牛客,线段树)

發布時間:2023/12/15 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 整数序列(牛客,线段树) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

鏈接:https://ac.nowcoder.com/acm/contest/160/D
來源:牛客網

題目描述
給出一個長度為n的整數序列a1,a2,…,an,進行m次操作,操作分為兩類。
操作1:給出l,r,v,將al,al+1,…,ar分別加上v;
操作2:給出l,r,詢問\sum\limits_{i=l}^{r}sin(a_i)
i=l

r
?
sin(a
i
?
)
輸入描述:
第一行一個整數n
接下來一行n個整數表示a1,a2,…,an
接下來一行一個整數m
接下來m行,每行表示一個操作,操作1表示為1 l r v,操作2表示為2 l r
保證1≤n,m,ai,v≤200000;1≤l≤r≤n,v是整數
輸出描述:
對每個操作2,輸出一行,表示答案,四舍五入保留一位小數
保證答案的絕對值大于0.1,且答案的準確值的小數點后第二位不是4或5
數據隨機生成(n,m人工指定,其余整數在數據范圍內均勻選取),并去除不滿足條件的操作2
示例1
輸入
復制
4
1 2 3 4
5
2 2 4
1 1 3 1
2 2 4
1 2 4 2
2 1 3
輸出
復制
0.3
-1.4
-0.3
區間修改加區間sin求和。
別管是修改還是求和都得是區間操作。肯定不能到葉子節點。。當一個區間內都加了v,對于當前節點來說,sin(x+v)=sinxcosv+cosxsinv;cos(x+v)=cosxcosv-sinxsinv;
如果左右兩個兒子節點都加了v,對于該節點來說,sum[cur]=sum[cur<<1]+sum[cur<<1|1]=sin(lx+v)+sin(rx+v)=cosv*(sinlx+sinrx)+sinv*(coslx+cosrx)。
這樣一看,我們要維護兩個之cos和sin。
代碼如下:

#include<bits/stdc++.h> #define ll long long using namespace std;const int maxx=2e5+100; struct node{int l;int r;double ssin;double ccon;ll lazy; }p[maxx<<2]; ll a[maxx]; int n,m;inline void pushup(int cur) {p[cur].ccon=p[cur<<1].ccon+p[cur<<1|1].ccon;p[cur].ssin=p[cur<<1].ssin+p[cur<<1|1].ssin; } inline void pushdown(int cur) {if(p[cur].lazy){ll v = p[cur].lazy;p[cur<<1].lazy+=v;p[cur<<1|1].lazy+=v;double tsin=p[cur<<1].ssin,tcos=p[cur<<1].ccon;p[cur<<1].ssin=tsin*cos(v)+tcos*sin(v);p[cur<<1].ccon=tcos*cos(v)-tsin*sin(v);tsin=p[cur<<1|1].ssin,tcos=p[cur<<1|1].ccon;p[cur<<1|1].ssin=tsin*cos(v)+tcos*sin(v);p[cur<<1|1].ccon=tcos*cos(v)-tsin*sin(v);p[cur].lazy=0;} } inline void build(int l,int r,int cur) {p[cur].l=l;p[cur].r=r;p[cur].ccon=p[cur].ssin=0.0;p[cur].lazy=0;if(l==r){p[cur].ssin=sin(a[l]);p[cur].ccon=cos(a[l]);return ;}int mid=l+r>>1;build(l,mid,cur<<1);build(mid+1,r,cur<<1|1);pushup(cur); } inline void update(int l,int r,int cur,ll z) {int L=p[cur].l;int R=p[cur].r;if(l<=L&&R<=r){p[cur].lazy+=z;double tsin=p[cur].ssin,tcos=p[cur].ccon;//這里注意,一定要把之前的值給記錄下來,否則會用更改之后的值。p[cur].ssin=cos(z)*tsin+sin(z)*tcos;p[cur].ccon=cos(z)*tcos-sin(z)*tsin;return ;}pushdown(cur);int mid=L+R>>1;if(r<=mid) update(l,r,cur<<1,z);else if(l>mid) update(l,r,cur<<1|1,z);else{update(l,mid,cur<<1,z);update(mid+1,r,cur<<1|1,z);}pushup(cur); } inline double query(int l,int r,int cur) {int L=p[cur].l;int R=p[cur].r;if(l<=L&&R<=r) return p[cur].ssin;pushdown(cur);int mid=L+R>>1;if(r<=mid) return query(l,r,cur<<1);else if(l>mid) return query(l,r,cur<<1|1);else return query(l,mid,cur<<1)+query(mid+1,r,cur<<1|1);//pushup(cur); } int main() {scanf("%d",&n);for(int i=1;i<=n;i++) scanf("%lld",&a[i]);build(1,n,1);int op,l,r;ll z;scanf("%d",&m);while(m--){scanf("%d%d%d",&op,&l,&r);if(op==1){scanf("%lld",&z);update(l,r,1,z);}else printf("%.1f\n",query(l,r,1));}return 0; }

努力加油a啊,(o)/~

總結

以上是生活随笔為你收集整理的整数序列(牛客,线段树)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。