2018陕西省赛K题[watermelon_planting]
生活随笔
收集整理的這篇文章主要介紹了
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]的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Alphabet第三季度营收766亿美元
- 下一篇: OpenAI首批投资者科斯拉:大多数AI