参考:http://www.cnblogs.com/qscqesze/p/4441225.html
看代码想想,思路也很简单,写在注释里了
#include <bits/stdc++.h>
using namespace std;
template <class T>
inline bool scan_d(T &ret)
{
char c;
int sgn;
if(c=getchar(),c==EOF) return 0;
while(c!='-'&&(c<'0'||c>'9')) c=getchar();
sgn=(c=='-')?-1:1;
ret=(c=='-')?0:(c-'0');
while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');
ret*=sgn;
return 1;
}
inline void out(int x)
{
if(x>9) out(x/10);
putchar(x%10+'0');
}
const int MAXN = 1e6+10;
int n,m,x,y;
int block,siz;
int Belong[MAXN];
double k[MAXN];//记录某个点的斜率
double maxv[MAXN];//记录一个块内的最大斜率
//记录一个块内,以块内第一个元素开始的一个上升序列,也就是在块的开头能看到的楼数
vector<double> see[1010];
int l[1010],r[1010];
void build()
{
memset(maxv,0,sizeof(maxv));
block = sqrt(n);
siz = n/block;
if(n%block) siz++;
for(int i = 1; i <= siz; ++i)
{
l[i] = (i-1)*block+1;
r[i] = i*block;
for(int j = l[i]; j <= r[i]; ++j)
Belong[j] = i;
}
r[siz] = n;
}
void update(int x, int y)
{
double xx = x;
double yy = y;
k[x] = yy/xx;
maxv[Belong[x]] = 0;
see[Belong[x]].clear();
double tmp = 0;
for(int i = l[Belong[x]]; i <= r[Belong[x]]; ++i)
{
if(k[i] > maxv[Belong[x]])
{
maxv[Belong[x]] = k[i];
see[Belong[x]].push_back(k[i]);
}
}
}
void query()
{
int res = 0;
double tmp = 0;
//每一次都记录下前一个块中最高的楼,在下一个块中二分
for(int i = 1; i <= siz; ++i)
{
if(!see[i].empty())
{
res += see[i].end()-upper_bound(see[i].begin(),see[i].end(),tmp);
tmp = max(tmp,maxv[i]);
}
}
out(res);
putchar('\n');
}
int main()
{
scan_d(n);
scan_d(m);
build();
while(m--)
{
scanf("%d %d",&x,&y);
update(x,y);
query();
}
return 0;
}