P2154 [SDOI2009]虔诚的墓主人(BIT)

Posted Harris-H

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P2154 [SDOI2009]虔诚的墓主人(BIT)相关的知识,希望对你有一定的参考价值。

P2154 [SDOI2009]虔诚的墓主人(BIT)

考虑按列统计答案

预处理每列所在的点,对这些点按照行排序。

我们知道对一个白点的贡献是: C U k × C D k × C L k × C R k C_U^k\\times C_D^k\\times C_L^k\\times C_R^k CUk×CDk×CLk×CRk

而对于同一列被黑点隔开的一段白点,他们的 C U k C_U^k CUk C D k C_D^k CDk相同。

因此我们只需要维护这些行的 ∑ C L k × C R k \\sum C_L^k\\times C_R^k CLk×CRk

先预处理得到每行的黑点数。

这样最开始 c n t R i cnt_R_i cntRi是已知的。

考虑用 B I T BIT BIT维护行的 C L k × C R k C_L^k\\times C_R^k CLk×CRk

然后每次扫完一列后,更新 B I T BIT BIT C L k × C R k → C L + 1 K C R − 1 K C_L^k\\times C_R^k\\rightarrow C_L+1^KC_R-1^K CLk×CRkCL+1KCR1K

黑点个数不超过 W W W个。

时间复杂度: O ( W l o g W ) O(WlogW) O(WlogW)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull; 
const int N=2e5+5,M=2e4+5,inf=0x3f3f3f3f;
const ll mod=1LL<<31;
const int hashmod[4] = 402653189,805306457,1610612741,998244353;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define PLL pair<ll,ll>
#define x first
#define y second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define per(i,a,b) for(int i=a;i>=b;--i)
#define ios ios::sync_with_stdio(false),cin.tie(nullptr) 
void Print(int *a,int n)
	for(int i=1;i<n;i++)
		printf("%d ",a[i]);
	printf("%d\\n",a[n]); 

template <typename T>		//x=max(x,y)  x=min(x,y)
void cmx(T &x,T y)
	if(x<y) x=y;

template <typename T>
void cmn(T &x,T y)
	if(x>y) x=y;

int n,m,w;
PII a[N];
int b[N<<1],sz;
ll c[N][11];
void init()
	sort(b+1,b+sz+1);
	sz =  unique(b+1,b+sz+1)-b-1;n = m = 0;
	rep(i,1,w)
		a[i].x=lower_bound(b+1,b+sz+1,a[i].x)-b;
		a[i].y=lower_bound(b+1,b+sz+1,a[i].y)-b;
		cmx(n,a[i].x),cmx(m,a[i].y);
	
	c[0][0] = 1;
	rep(i,1,N-1)
		c[i][0]  = 1;
		rep(j,1,10)
			c[i][j] = (c[i-1][j] + c[i-1][j-1]) % mod;
	

ll s[N];
#define lowbit(x) x&(-x)
ll que(int x)
	ll ans=0;
	while(x)
		ans+=s[x];
		x-=lowbit(x);
	
	return ans;

void upd(int x,ll v)
	while(x<=m)
		s[x]+=v;
		x+=lowbit(x);
	

ll que_(int l,int r)
	if(l>r) return 0;
	return (que(r)-que(l-1))%mod;

void upd_(int x,ll v)
	upd(x,-que_(x,x));
	upd(x,v);

int sum[N],now[N];
vector<int>v[N];
int main()
	scanf("%d%d%d",&n,&m,&w);
	rep(i,1,w) 
	scanf("%d%d",&a[i].x,&a[i].y),b[++sz]=a[i].x,b[++sz]=a[i].y;
	int k;scanf("%d",&k);
	init();
	rep(i,1,w)
	v[a[i].x].push_back(a[i].y);
	sum[a[i].y]++;
	

	rep(i,1,n) sort(v[i].begin(),v[i].end());

	ll ans=0;
	rep(i,1,n)
		for(int j=0;SZ(v[i])>1 && j<SZ(v[i])-1; j++)

			ans+=((c[j+1][k]*c[SZ(v[i])-j-1][k])%mod*que_(v[i][j]+1,v[i][j+1]-1))%mod;
			ans%=mod;

		
		for(int x:v[i])
			now[x]++;
			upd_(x,c[now[x]][k]*c[sum[x]-now[x]][k]%mod);
		
	
	printf("%lld\\n",(ans%mod+mod)%mod);
	return 0;

以上是关于P2154 [SDOI2009]虔诚的墓主人(BIT)的主要内容,如果未能解决你的问题,请参考以下文章

SDOI2009 虔诚的墓主人

[SDOI2009] 虔诚的墓主人

bzoj 1227: [SDOI2009]虔诚的墓主人

BZOJ1227: [SDOI2009]虔诚的墓主人

bzoj 1227: [SDOI2009]虔诚的墓主人

Bzoj 1227: [SDOI2009]虔诚的墓主人 树状数组,离散化,组合数学