【BZOJ4627】[BeiJing2016]回轉壽司 SBT
阿新 • • 發佈:2017-10-15
iostream 註意 class 而是 吃貨 不同 () esp font
第一行包含三個整數N,L和R,分別表示壽司盤數,滿意度的下限和上限。
第二行包含N個整數Ai,表示小Z對壽司的滿意度。
N≤100000,|Ai|≤100000,0≤L, R≤10^9
1 2 3 4 5
【BZOJ4627】[BeiJing2016]回轉壽司
Description
酷愛日料的小Z經常光顧學校東門外的回轉壽司店。在這裏,一盤盤壽司通過傳送帶依次呈現在小Z眼前。不同的壽司帶給小Z的味覺感受是不一樣的,我們定義小Z對每盤壽司都有一個滿意度,例如小Z酷愛三文魚,他對一盤三文魚壽司的滿意度為10;小Z覺得金槍魚沒有什麽味道,他對一盤金槍魚壽司的滿意度只有5;小Z最近看了電影“美人魚”,被裏面的八爪魚惡心到了,所以他對一盤八爪魚刺身的滿意度是-100。特別地,小Z是個著名的吃貨,他吃回轉壽司有一個習慣,我們稱之為“狂吃不止”。具體地講,當他吃掉傳送帶上的一盤壽司後,他會毫不猶豫地吃掉它後面的壽司,直到他不想再吃壽司了為止。今天,小Z再次來到了這家回轉壽司店,N盤壽司將依次經過他的面前,其中,小Z對第i盤壽司的滿意度為Ai。小Z可以選擇從哪盤壽司開始吃,也可以選擇吃到哪盤壽司為止,他想知道共有多少種不同的選擇,使得他的滿意度之和不低於L,且不高於R。註意,雖然這是回轉壽司,但是我們不認為這是一個環上的問題,而是一條線上的問題。即,小Z能吃到的是輸入序列的一個連續子序列;最後一盤轉走之後,第一盤並不會再出現一次。Input
Output
僅一行,包含一個整數,表示共有多少種選擇可以使得小Z的滿意度之和不低於L且不高於R。Sample Input
5 5 91 2 3 4 5
Sample Output
6題解:首先區間和可以表示成前綴相減,那麽我們對於當前的前綴和s[i],只需要統計j<i,L<=s[i]-s[j]<=R的個數即可。可以用SBT實現。
#include <cstdio> #include <iostream> #include <cstring> using namespace std; const int maxn=100010; typedef long long ll; int n,tot,rt; ll ans; ll v[maxn],L,R; struct node { int siz,ch[2]; ll val; }s[maxn]; inline void pushup(int x) { s[x].siz=s[s[x].ch[0]].siz+s[s[x].ch[1]].siz+1; } inline void rotate(int &x,int d) { int y=s[x].ch[d]; s[x].ch[d]=s[y].ch[d^1],s[y].ch[d^1]=x; pushup(x),pushup(y); x=y; } void maintain(int &x,int d) { if(s[s[s[x].ch[d]].ch[d]].siz>s[s[x].ch[d^1]].siz) rotate(x,d); else if(s[s[s[x].ch[d]].ch[d^1]].siz>s[s[x].ch[d^1]].siz) rotate(s[x].ch[d],d^1),rotate(x,d); else return ; maintain(s[x].ch[d],d),maintain(s[x].ch[d^1],d^1); maintain(x,d),maintain(x,d^1); } void insert(int &x,ll y) { if(!x) { x=++tot; s[x].siz=1,s[x].ch[0]=s[x].ch[1]=0,s[x].val=y; return ; } int d=(y>s[x].val); insert(s[x].ch[d],y),s[x].siz++; maintain(x,d); } int qless(int x,ll y) { if(!x) return 0; if(s[x].val>=y) return qless(s[x].ch[0],y); else return s[s[x].ch[0]].siz+1+qless(s[x].ch[1],y); } int qmore(int x,ll y) { if(!x) return 0; if(s[x].val<=y) return qmore(s[x].ch[1],y); else return s[s[x].ch[1]].siz+1+qmore(s[x].ch[0],y); } inline char nc() { static char buf[100000],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++; } inline int rd() { int ret=0,f=1; char gc=nc(); while(gc<‘0‘||gc>‘9‘) {if(gc==‘-‘) f=-f; gc=nc();} while(gc>=‘0‘&&gc<=‘9‘) ret=ret*10+gc-‘0‘,gc=nc(); return ret*f; } int main() { n=rd(),L=rd(),R=rd(); int i; for(i=1;i<=n;i++) { insert(rt,v[i-1]); v[i]=rd()+v[i-1]; ans+=i-qmore(rt,v[i]-L)-qless(rt,v[i]-R); } printf("%lld",ans); return 0; }//5 5 9 1 2 3 4 5
【BZOJ4627】[BeiJing2016]回轉壽司 SBT