Educational Codeforces Round 41 (Rated for Div. 2) E. Tufurama(树状数组)

题目链接:http://codeforces.com/contest/961/problem/E


就是每次问一个区间有多少数大于k,直接离线树状数组就好了。


代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN=2e5+5;
int a[MAXN];
struct query
{
	int pos,k,val;
	query(int _pos=0,int _k=0,int _val=0):pos(_pos),k(_k),val(_val){}
	bool operator < (const query &o)const
	{
		return pos<o.pos;
	}
}Q[MAXN*2];
struct BIT
{
	int b[MAXN],n;
	void init(int _n)
	{
		n=_n;
		memset(b,0,sizeof(b));
	}
	inline int lowbit(int x)
	{
		return x&(-x);
	}
	void update(int x,int val)
	{
		while(x<=n)
		{
			b[x]+=val;
			x+=lowbit(x);
		}
	}
	int query(int x)
	{
		int ret=0;
		while(x)
		{
			ret+=b[x];
			x-=lowbit(x);
		}
		return ret;
	}
}bit;
int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	int n,tot=0;
	scanf("%d",&n);
	bit.init(n);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
		a[i]=min(a[i],n);
		if(a[i]<=i) continue;
		Q[++tot]=query(i,i-1,-1);
		Q[++tot]=query(a[i],i-1,1);
	}
	sort(Q+1,Q+1+tot);
	ll ans=0,p=1;
	for(int i=1;i<=n;i++)
	{
		bit.update(a[i],1);
		while(Q[p].pos<=i&&p<=tot)
		{
			int k=Q[p].k;
			int cnt=bit.query(n)-bit.query(k);
			ans+=Q[p].val*cnt;
			p++;
		}
	}
	printf("%lld\n",ans);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/sinat_32872703/article/details/80260904