[POI2015]Logistyka

[POI2015]Logistyka

题目大意:

一个长度为\(n(n\le10^6)\)的数列\(A_i\),初始全为\(0\)。操作共\(m(m\le10^6)\)次,包含以下两种:

  1. \(A_x\)修改为\(y\)
  2. 询问若每次任意选择\(x\)个正数,将它们\(-1\),能否操作\(y\)次。

思路:

\(cnt\)表示不小于\(y\)的数的个数,\(sum\)表示小于\(y\)的数之和。

一个结论是,当\(sum\ge(x-cnt)\times y\)时可行,否则不可行。

证明参考Claris博客

时间复杂度\(\mathcal O(m\log n)\)

源代码:

#include<cstdio>
#include<cctype>
#include<algorithm>
inline int getint() {
	register char ch;
	while(!isdigit(ch=getchar()));
	register int x=ch^'0';
	while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
	return x;
}
inline char getalpha() {
	register char ch;
	while(!isalpha(ch=getchar()));
	return ch;
}
const int N=1e6+1,M=1e6;
typedef long long int64;
struct Query {
	bool opt;
	int x,y;
};
Query q[M];
int tmp[N],w[N];
class SegmentTree {
	#define _left <<1
	#define _right <<1|1
	#define mid ((b+e)>>1)
	private:
		int64 val[2][N<<2],*cnt,*sum;
		void push_up(const int &p) {
			cnt[p]=cnt[p _left]+cnt[p _right];
			sum[p]=sum[p _left]+sum[p _right];
		}
	public:
		SegmentTree() {
			cnt=val[0];
			sum=val[1];
		}
		void modify(const int &p,const int &b,const int &e,const int &x,const int &y) {
			if(b==e) {
				cnt[p]+=y;
				sum[p]+=tmp[x]*y;
				return;
			}
			if(x<=mid) modify(p _left,b,mid,x,y);
			if(x>mid) modify(p _right,mid+1,e,x,y);
			push_up(p);
		}
		int64 query(const int &p,const int &b,const int &e,const int &l,const int &r,const bool &t) const {
			if(b==l&&e==r) return val[t][p];
			int64 ret=0;
			if(l<=mid) ret+=query(p _left,b,mid,l,std::min(mid,r),t);
			if(r>mid) ret+=query(p _right,mid+1,e,std::max(mid+1,l),r,t);
			return ret;
		}
	#undef _left
	#undef _right
	#undef mid
};
SegmentTree t;
int main() {
	const int n=getint(),m=getint();
	for(register int i=0;i<m;i++) {
		const char opt=getalpha();
		const int x=getint(),y=getint();
		q[i]=(Query){opt=='Z',x,y};
		tmp[++tmp[0]]=y;
	}
	std::sort(&tmp[1],&tmp[tmp[0]]+1);
	tmp[0]=std::unique(&tmp[1],&tmp[tmp[0]]+1)-&tmp[1];
	for(register int i=0;i<m;i++) {
		q[i].y=std::lower_bound(&tmp[1],&tmp[tmp[0]]+1,q[i].y)-tmp;
		const int &x=q[i].x,&y=q[i].y;
		if(q[i].opt) {
			const int cnt=t.query(1,1,tmp[0],y,tmp[0],0);
			const int64 sum=y!=1?t.query(1,1,tmp[0],1,y-1,1):0;
			puts(sum>=(int64)(x-cnt)*tmp[y]?"TAK":"NIE");
		} else {
			if(w[x]) t.modify(1,1,tmp[0],w[x],-1);
			w[x]=y;
			if(w[x]) t.modify(1,1,tmp[0],w[x],1);
		}
	}
	return 0;
}
posted @ 2018-09-02 10:55  skylee03  阅读(115)  评论(0编辑  收藏  举报