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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

YbtOJ#20066-[NOIP2020模拟赛B组Day4]筹备计划【线段树,树状数组】

發布時間:2023/12/3 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 YbtOJ#20066-[NOIP2020模拟赛B组Day4]筹备计划【线段树,树状数组】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

正題

題目鏈接:http://noip.ybtoj.com.cn/contest/90/problem/4


題目大意

一個集合[1,n]∈S[1,n]\in S[1,n]S,和一個序列aaa。有操作

  • 序列aaa的一個數加上xxx
  • 序列aaa的一個數減去xxx
  • [l,r][l,r][l,r]加入集合SSS
  • [l,r][l,r][l,r]刪除出集合SSS
  • 每次修改后求一個k∈Sk\in SkS使得∑i=1∣i?k∣ai\sum_{i=1}|i-k|a_ii=1?i?kai?最小


    解題思路

    如果不考慮集合SSS來選數那么一定是選序列aia_iai?的帶權中位數(((即有aia_iai?iii)))。

    那么考慮上集合SSS一定是選擇離SSS近的,我們直接找到左右兩邊最近的值然后用樹狀數組判斷答案大小即可。

    時間復雜度O(nlog?n)O(n\log n)O(nlogn)


    codecodecode

    #include<cstdio> #include<cstring> #include<algorithm> #define lowbit(x) (x&-x) #define ll long long using namespace std; const ll N=2e5+10; ll n,q; struct Seq_Tree{ll s[N*4],lazy[N*4],w[N*4];void Downdata(ll x,ll l,ll mid,ll r){if(!lazy[x])return;lazy[x*2]=lazy[x*2+1]=lazy[x];lazy[x]--;s[x*2]=(mid-l+1)*lazy[x];s[x*2+1]=(r-mid)*lazy[x];lazy[x]=0;return;}void Cover(ll x,ll L,ll R,ll l,ll r,ll val){if(L==l&&R==r){s[x]=(R-L+1)*val;lazy[x]=val+1;return;}ll mid=(L+R)>>1;Downdata(x,L,mid,R);if(r<=mid)Cover(x*2,L,mid,l,r,val);else if(l>mid)Cover(x*2+1,mid+1,R,l,r,val);else Cover(x*2,L,mid,l,mid,val),Cover(x*2+1,mid+1,R,mid+1,r,val);s[x]=s[x*2]+s[x*2+1];w[x]=w[x*2]+w[x*2+1];return;}void Change(ll x,ll L,ll R,ll pos,ll val){if(L==R){w[x]+=val;return;}ll mid=(L+R)>>1;Downdata(x,L,mid,R);if(pos<=mid)Change(x*2,L,mid,pos,val);else Change(x*2+1,mid+1,R,pos,val);s[x]=s[x*2]+s[x*2+1];w[x]=w[x*2]+w[x*2+1];}ll Find(ll x,ll L,ll R,ll k){if(L==R)return s[x];ll mid=(L+R)>>1;Downdata(x,L,mid,R);if(w[x*2]>=k)return Find(x*2,L,mid,k);return s[x*2]+Find(x*2+1,mid+1,R,k-w[x*2]);}ll Ask(ll x,ll L,ll R,ll k){if(L==R)return L;ll mid=(L+R)>>1;Downdata(x,L,mid,R);if(s[x*2]>=k)return Ask(x*2,L,mid,k);return Ask(x*2+1,mid+1,R,k-s[x*2]);} }T; struct BIT{ll t[N],w[N];void Change(ll x,ll val){ll k=n-x+1;while(x<=n){t[x]+=val*k;w[x]+=val;x+=lowbit(x); }return;}ll Ask(ll x){ll ans=0,k=n-x+1;while(x){ans+=t[x]-w[x]*k;x-=lowbit(x);}return ans;} }Tl,Tr; ll check(ll x) {return Tl.Ask(x)+Tr.Ask(n-x+1);} void updata(ll x,ll w){Tl.Change(x,w);Tr.Change(n-x+1,w);return; } int main() {freopen("position.in","r",stdin);freopen("position.out","w",stdout);scanf("%lld%lld",&n,&q);for(ll i=1;i<=n;i++){ll x;scanf("%lld",&x);T.Change(1,0,n+1,i,x);Tl.Change(i,x);Tr.Change(n-i+1,x);}T.Cover(1,0,n+1,0,n+1,1);while(q--){ll op,x,y;scanf("%lld%lld%lld",&op,&x,&y);if(op==1)T.Change(1,0,n+1,x,y),updata(x,y); if(op==2)T.Change(1,0,n+1,x,-y),updata(x,-y);if(op==3)T.Cover(1,0,n+1,x,y,1);if(op==4)T.Cover(1,0,n+1,x,y,0);ll k=T.Find(1,0,n+1,(T.w[1]+1)/2);x=T.Ask(1,0,n+1,k);y=T.Ask(1,0,n+1,k+1);if(!x&&y==n+1)printf("-1\n");else if(!x)printf("%lld\n",y);else if(y==n+1)printf("%lld\n",x);else if(check(x)<=check(y))printf("%lld\n",x);else printf("%lld\n",y);} }

    總結

    以上是生活随笔為你收集整理的YbtOJ#20066-[NOIP2020模拟赛B组Day4]筹备计划【线段树,树状数组】的全部內容,希望文章能夠幫你解決所遇到的問題。

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