YbtOJ#20066-[NOIP2020模拟赛B组Day4]筹备计划【线段树,树状数组】
生活随笔
收集整理的這篇文章主要介紹了
YbtOJ#20066-[NOIP2020模拟赛B组Day4]筹备计划【线段树,树状数组】
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
正題
題目鏈接:http://noip.ybtoj.com.cn/contest/90/problem/4
題目大意
一個(gè)集合[1,n]∈S[1,n]\in S[1,n]∈S,和一個(gè)序列aaa。有操作
每次修改后求一個(gè)k∈Sk\in Sk∈S使得∑i=1∣i?k∣ai\sum_{i=1}|i-k|a_ii=1∑?∣i?k∣ai?最小
解題思路
如果不考慮集合SSS來(lái)選數(shù)那么一定是選序列aia_iai?的帶權(quán)中位數(shù)(((即有aia_iai?個(gè)iii)))。
那么考慮上集合SSS一定是選擇離SSS近的,我們直接找到左右兩邊最近的值然后用樹(shù)狀數(shù)組判斷答案大小即可。
時(shí)間復(fù)雜度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);} }總結(jié)
以上是生活随笔為你收集整理的YbtOJ#20066-[NOIP2020模拟赛B组Day4]筹备计划【线段树,树状数组】的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: lol飞机出装 大神来教你
- 下一篇: 生辰花和诞生花的区别 关于生辰花和诞生花