問題 G: 鴿子 (gu)-------------------------思維(二維樹狀數組)

題目描述
一共有n個人依次走進機房,第i個人的實力爲ai。

第i個人在走進機房時,會膜拜當前已經在機房裏的人x,當且僅當ax>ai。

同理,第i個人在走進機房時,會被當前已經在機房裏的人x膜拜,當且僅當ax<ai。

第i個人的音量爲vi。設他在走進機房的時候,膜拜了k個人,那麼,他會產生vi×k的噪音值。

假設他走進機房時,膜拜他的人的集合爲{s1,s2,s3,…,sm},那麼這些人會產生***的噪音值。

ctt2006巨佬想知道,每個人走進機房時,當前總共會產生多少噪音值。由於他忙着吊打集訓隊,於是把問題交給
輸入
第一行一個正整數n,表示人數。
接下來n行,每行兩個數ai,vi,意義見題目描述。
輸出
一行n個數,以空格分隔。第i個數表示第i個人走進機房時(包括之前)產生的噪音。
由於這些值可能很大,只要輸出它們mod 998244353的值即可。
樣例輸入 Copy
5
3 1
2 3
1 4
5 2
4 5
樣例輸出 Copy
0 3 11 19 32
提示
樣例1解釋:
第一個人走進機房,由於只有一個人,噪音爲0;
第二個人走進機房,比他強的有1,沒有比他弱的人,當前總共產生:3×1=3噪音;
第三個人走進機房,比他強的有1,2,沒有比他弱的人,當前總共產生:3×1+4×2=11噪音;
第四個人走進機房,沒有比他強的人,比他弱的人有1,2,3,當前總共產生:3×1+4×2+1+3+4=19噪音;
第五個人走進機房,比他強的有4,比他弱的有1,2,3,當前總共產生:3×1+4×2+1+3+4+1+3+4+5=19噪音。

解析:

由題意可知,每個人進入機房都需要維護兩個值,
一個是膜拜第i個人的噪音總和
一個是第i個人膜拜機房大佬的總和
對於第一個值,我們只要二維樹狀數組維護即可

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MOD=998244353;
const int N=5e5+10000;
ll c[N][2];
ll a[N],b[N],num[N];
ll sum[N];
int n;
int lowbit(int x)
{
	return x&(-x);
}
void add(int i,int val,int u)
{
	while(i<N)
	{
		c[i][u]=(c[i][u]+val)%MOD;
		i+=lowbit(i);
	}
}
ll ask(int i,int u)
{
	ll res=0;
	while(i)
	{
		res=(res+c[i][u])%MOD;
		i-=lowbit(i);
	}
	return res;
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)scanf("%lld %lld",&a[i],&b[i]),num[i]=a[i];
	sort(num+1,num+1+n);
	int m=unique(num+1,num+1+n)-num;
	for(int i=1;i<=n;i++)
	{
		int k=lower_bound(num+1,num+1+m,a[i])-num;
		//cout<<k<<endl;
		add(k,1,1);add(k,b[i],2);
		
		ll val=ask(k-1,2);
	
		val=(val+(ask(N-1,1)-ask(k,1))*b[i]%MOD)%MOD;
		sum[i]=val;
	}
	for(int i=1;i<=n;i++)
	{
		sum[i]=(sum[i-1]+sum[i])%MOD;
		cout<<sum[i]%MOD<<" ";
	}
	
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章