POI21填坑计划
数据结构乱做

BZOJ2957

HJWJBSR posted @ 2015年12月25日 16:43 in 题解 , 532 阅读

之前不知为何记得这个是树套树好题于是抽空做了一下。思索很久无果。

感觉倒是线段树还有分块做法一下就想出来了。。(其实线段树做法是因为刚好做过一道差不多的题才会做= =)

线段树做法很优美啊:

维护每段区间的答案。还有这个答案的右端点。

Update的时候套个询问就好了。具体可以看这里

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
#define N 100050
double bd[N*4];int Ans[N*4],n,m;
inline int Read()
 {
 	int x=0;char y;
 	do y=getchar(); while (y<'0'||y>'9');
 	do x=x*10+y-'0',y=getchar(); while (y>='0'&&y<='9');
 	return x;
 }
inline double max(double x,double y)
 {return x<y?y:x;}
int Query(int x,int y,int z,double o)
 {
 	int i=x + y >> 1,j=z << 1;
 	if (x==y) return bd[z]>o;
 	if (bd[j]<=o) return Query(i+1,y,j+1,o); else
 	  return Ans[z]-Ans[j]+Query(x,i,j,o);
 }
void Modify(int x,int y,int z,int o,double p)
 {
 	int i=x + y >> 1,j=z << 1;
 	if (x==y) {Ans[z]=1;bd[z]=p;return;}
 	if (o<=i) Modify(x,i,j,o,p); else
 	  Modify(i+1,y,j+1,o,p);
 	bd[z]=max(bd[j],bd[j+1]);
 	Ans[z]=Ans[j]+Query(i+1,y,j+1,bd[j]);
 	return;
 }
int main()
 {
 	n=Read();m=Read();
 	while (m--)
 	 {
 	 	int k=Read(),l=Read();Modify(1,n,1,k,l*1.0/k);
 	 	printf("%d\n",Ans[1]);
 	 }
 	return 0;
 }

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter