1. 程式人生 > >【BZOJ4627】[BeiJing2016]回轉壽司 SBT

【BZOJ4627】[BeiJing2016]回轉壽司 SBT

iostream 註意 class 而是 吃貨 不同 () esp font

【BZOJ4627】[BeiJing2016]回轉壽司

Description

酷愛日料的小Z經常光顧學校東門外的回轉壽司店。在這裏,一盤盤壽司通過傳送帶依次呈現在小Z眼前。不同的壽司帶給小Z的味覺感受是不一樣的,我們定義小Z對每盤壽司都有一個滿意度,例如小Z酷愛三文魚,他對一盤三文魚壽司的滿意度為10;小Z覺得金槍魚沒有什麽味道,他對一盤金槍魚壽司的滿意度只有5;小Z最近看了電影“美人魚”,被裏面的八爪魚惡心到了,所以他對一盤八爪魚刺身的滿意度是-100。特別地,小Z是個著名的吃貨,他吃回轉壽司有一個習慣,我們稱之為“狂吃不止”。具體地講,當他吃掉傳送帶上的一盤壽司後,他會毫不猶豫地吃掉它後面的壽司,直到他不想再吃壽司了為止。今天,小Z再次來到了這家回轉壽司店,N盤壽司將依次經過他的面前,其中,小Z對第i盤壽司的滿意度為Ai。小Z可以選擇從哪盤壽司開始吃,也可以選擇吃到哪盤壽司為止,他想知道共有多少種不同的選擇,使得他的滿意度之和不低於L,且不高於R。註意,雖然這是回轉壽司,但是我們不認為這是一個環上的問題,而是一條線上的問題。即,小Z能吃到的是輸入序列的一個連續子序列;最後一盤轉走之後,第一盤並不會再出現一次。

Input

第一行包含三個整數N,L和R,分別表示壽司盤數,滿意度的下限和上限。 第二行包含N個整數Ai,表示小Z對壽司的滿意度。 N≤100000,|Ai|≤100000,0≤L, R≤10^9

Output

僅一行,包含一個整數,表示共有多少種選擇可以使得小Z的滿意度之和不低於L且不高於R。

Sample Input

5 5 9
1 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