我就是喜欢分块!!!
我的题库:https://blog.csdn.net/L_Y_T020321/article/details/83152606
首先,先来放一下题面占空间
题目描述
人比人,气死人;鱼比鱼,难死鱼。小鱼最近参加了一个“比可爱”比赛,比的是每只鱼的可爱程度。参赛的鱼被从左到右排成一排,头都朝向左边,然后每只鱼会得到一个整数数值,表示这只鱼的可爱程度,很显然整数越大,表示这只鱼越可爱,而且任意两只鱼的可爱程度可能一样。由于所有的鱼头都朝向左边,所以每只鱼只能看见在它左边的鱼的可爱程度,它们心里都在计算,在自己的眼力范围内有多少只鱼不如自己可爱呢。请你帮这些可爱但是鱼脑不够用的小鱼们计算一下。
输入输出格式
输入格式:
第一行输入一个整数n,表示鱼的数目。
第二行内输入n个整数,用空格间隔,依次表示从左到右每只小鱼的可爱程度。
输出格式:
行内输出n个整数,用空格间隔,依次表示每只小鱼眼中有多少只鱼不如自己可爱。
输入输出样例
输入样例#1:
6
4 3 0 5 1 2
输出样例#1:
0 0 0 3 1 2
说明
n<=100
有人不解的问:这不就是一道luogu红题么?为毛要分块啊!!
然后,我解释说:这叫作分块中毒综合征
算了,直接上code吧
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
int n,N;
int pos[51000],s[51000],tag[51000];
vector<int> v[510];
int query(int x,int y,int c)
{
int ans=0;
for (int i=x;i<=min(pos[x]*N,y);i++)
if (s[i]+tag[pos[x]]<c) ans++;
if (pos[x]!=pos[y])
{
for (int i=((pos[y]-1)*N+1);i<=y;i++) if (s[i]+tag[pos[y]]<c) ans++;
}
for (int i=pos[x]+1;i<pos[y];i++)
{
int t=c-tag[i];
ans+=lower_bound(v[i].begin(),v[i].end(),t)-v[i].begin();
}
return ans;
}
int main()
{
scanf("%d",&n);
N=sqrt(n);
for (int i=1;i<=n;i++) scanf("%d",&s[i]);
for (int i=1;i<=n;i++)
{
pos[i]=(i-1)/N+1;
v[pos[i]].push_back(s[i]);
}
for (int i=1;i<=pos[n];i++)
sort(v[i].begin(),v[i].end());
for(int i = 1 ; i <= n ; i ++) {
cout << query(1,i,s[i]) <<" ";
}
return 0;
}
code就不作任何解释了
其实,这道题我的思路就是求枚举每条鱼,找1~i条鱼中所有小与 a i a_i ai的个数就好了!!
所以,这道题来做分块最棒了!!!