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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

2018陕西省赛K题[watermelon_planting]

發布時間:2023/12/3 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2018陕西省赛K题[watermelon_planting] 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題意:有一個序列a[],描述的是另一個序列ans[]每個位置單位時間的增量。每個單位時間每個位置都會增加一個單位對應增量。時間總長m,每個單位時間包含有兩種操作中的一個:1.詢問ans[]在[l,r]區間的和;2.修改:a[]在[l,r]區間+1,即[l,r]區間的ans[]增量+1,a[i], n,m?≤?10^5

題解:當時腦抽沒想出來,現在覺得好簡單。。。考慮對每個位置,維護一個關于時間的一次函數y=a*x+b,y:是這個位置的答案,x:是時間,然后就維護兩個系數a,b就可以了。維護的方法就是開兩顆線段樹分別維護a,b,這就是個裸的區間加,區間求和。位置i系數的表達式:a = (ai + 修改次數),b = - (修改的時間和)。隨機跑了跑沒啥大問題,發現問題歡迎評論區指出。(大概一輩子都是桶排選手吧。)

#include <bits/stdc++.h> typedef long long ll; const int N = 1e5 + 100; using namespace std; int n,m; ll a[N]; struct seg{int l,r;ll sum,tag;}tree[2][N<<2]; void push_up(int p,seg* tree) {tree[p].sum = tree[p<<1].sum + tree[p<<1|1].sum; } void push_down(int p,seg* tree) {if(tree[p].tag) {tree[p<<1].sum += 1LL*(tree[p<<1].r - tree[p<<1].l + 1)*tree[p].tag;tree[p<<1|1].sum += 1LL*(tree[p<<1|1].r - tree[p<<1|1].l + 1)*tree[p].tag;tree[p<<1].tag += tree[p].tag;tree[p<<1|1].tag += tree[p].tag;tree[p].tag = 0;} } void build(int p, int l, int r, seg* tree) {tree[p].l = l; tree[p].r = r;tree[p].sum = tree[p].tag = 0;if(l == r) {tree[p].sum = a[l]; return;}int mid = (l + r) >> 1;build(p<<1, l, mid, tree), build(p<<1|1, mid+1, r, tree);push_up(p, tree); } void buildb(int p, int l, int r, seg* tree) {tree[p].l = l; tree[p].r = r;tree[p].sum = tree[p].tag = 0;if(l == r) return;int mid = (l + r) >> 1;buildb(p<<1, l, mid, tree), buildb(p<<1|1, mid+1, r, tree);push_up(p, tree); } void add(int p, int l, int r, ll x,seg* tree) {if(tree[p].l == l && tree[p].r ==r) {tree[p].sum += 1LL*(r-l+1)*x;tree[p].tag += x;return;}int mid = (tree[p].l + tree[p].r) >> 1;push_down(p, tree);if(r <= mid) add(p<<1, l, r, x, tree);else if(l > mid) add(p<<1|1, l, r, x, tree);else add(p<<1, l, mid, x, tree), add(p<<1|1, mid+1, r, x, tree);push_up(p, tree); } ll ask(int p, int l, int r,seg* tree) {if(tree[p].l == l && tree[p].r == r) return tree[p].sum;push_down(p, tree);int mid = (tree[p].l + tree[p].r) >> 1;if(r <= mid) return ask(p<<1, l, r, tree);else if(l > mid) return ask(p<<1|1, l, r, tree);else return ask(p<<1, l, mid, tree) + ask(p<<1|1, mid+1, r, tree); } //ll ans[N]; //void update(int l,int r){ // for(int i=1;i<=n;++i)ans[i]+=a[i]; // for(int i=l;i<=r;++i)++a[i]; //} //ll ask2(int l,int r){ll res=0; // for(int i=1;i<=n;++i)ans[i]+=a[i]; // for(int i=l;i<=r;++i)res+=ans[i]; // return res; //} int main() {while(scanf("%d",&n)) {for(int i=1;i<=n;++i)scanf("%lld",&a[i]);//,ans[i]=0;build(1,1,n,tree[0]);buildb(1,1,n,tree[1]);scanf("%d",&m);for(int i=1;i<=m;++i) {char opt;int l,r;scanf(" %c %d %d",&opt,&l,&r);//opt=rand()%2;l=rand()%n+1,r=rand()%n+1;if(l>r)swap(l,r);//printf("%d : [%d,%d]\n",opt,l,r);if(opt=='Q'){ll ans = ask(1,l,r,tree[0])*i-ask(1,l,r,tree[1]);//ll ans2=ask2(l,r);printf("%lld\n",ans); // if(ans!=ans2){ // printf("_______________________\n"); // }}else {add(1,l,r,1,tree[0]);add(1,l,r,i,tree[1]); // update(l,r);}}}return 0; }

?

轉載于:https://www.cnblogs.com/RRRR-wys/p/9074789.html

總結

以上是生活随笔為你收集整理的2018陕西省赛K题[watermelon_planting]的全部內容,希望文章能夠幫你解決所遇到的問題。

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