(联考)noip99


T1

CF1503E

T2

距离最远的一定是直径的两个端点之一。

于是把操作倒过来做,并查集维护连通块内直径的两个端点即可。

T3

矩形问题,可以考虑一手扫描线。

\(k\) 很小,所以可以用线段树维护前k小, Push_up的时候归并合并(类似归并排序的一个玩意),然后就可以求出每一行有多少个male monkey,多少个female monkey,于是这题没了。

离线处理询问,可以做到 \(O(1)\) 回答,在线多带个 \(\log\)

Code
#include
#include
#include
#include
using std::sort;
using std::pair;
using std::vector;
#define re register
#define x(p) p.first
using std::make_pair;
#define y(p) p.second
#define make make_pair
const int MAX = 3e5+3;
using std::lower_bound;
#define long long long
#define scanf oma=scanf
typedef pair my;
#define pack emplace_back
#define freopen file=freopen
int oma;
FILE* file;
namespace some
{
	struct stream
	{
		templateinline stream &operator >>(type &s)
		{
			bool w=0; s=0; char ch=getchar();
			while(!isdigit(ch)){ w|=ch=='-'; ch=getchar(); }
			while(isdigit(ch)){ s=(s<<1)+(s<<3)+(ch^48); ch=getchar(); }
			return s=w?-s:s,*this;
		}
	}cin;
	long res[MAX];
	int n,m,c,k,q;
	long pre[MAX][2];
	vector>w[MAX];
	#define debug(s) printf("%s\n",s)
	auto min = [](int a,int b) { return ak;
		}st[MAX<<2];
		#define ls(p) p<<1
		#define rs(p) p<<1|1
		#define k(p) st[p].k
		#define mid (l+r>>1)
		my rec[MAX<<1];
		void Push_up(int p,int pos = 0,int cnt = 0)
		{
			k(p).clear();
			for(auto z : k(ls(p)))
			{
				while(pos<=k(rs(p)).size()-1&&k(rs(p))[pos]<=z)
				{ rec[++cnt] = (k(rs(p))[pos++]); }
				rec[++cnt] = (z);
			}
			while(pos<=k(rs(p)).size()-1)
			{ rec[++cnt] = (k(rs(p))[pos++]); }
			k(p).pack(rec[1]);
			for(re int i=2; i<=cnt; i++)
			{
				my z = rec[i];
				if(x(k(p)[k(p).size()-1])==x(z))
				{ y(k(p)[k(p).size()-1]) += y(z); }
				else
				{ k(p).pack(z); }
			}
			while(k(p).size()-1>k)
			{ k(p).pop_back(); }
		}
		void build(int p,int l,int r)
		{
			if(l==r)
			{ k(p).pack(make(0,1)); return ; }
			build(ls(p),l,mid),build(rs(p),mid+1,r);
			Push_up(p);
		}
		void Push_down(int p)
		{
			if(st[p].lazy)
			{
				for(re int i=0; imid)
			{ modify(rs(p),mid+1,r,lp,rp,val); }
			Push_up(p);
		}
	}Tree;
}using namespace Data_Structures;
namespace OMA
{
	auto main = []() -> signed
	{
		//#define local
		#ifdef local
		debug("look here!if you want submit,please closed this");
		freopen("node.in","r",stdin); freopen("my.out","w",stdout);
		#endif
		freopen("army.in","r",stdin); freopen("army.out","w",stdout);
		cin >> n >> m >> c >> k >> q;
		for(re int i=1,x1,y1,x2,y2; i<=c; i++)
		{ cin >> x1 >> y1 >> x2 >> y2; w[x1].pack(make(make(y1,y2),1)),w[x2+1].pack(make(make(y1,y2),-1)); }
		Tree.build(1,1,m);
		for(re int i=1; i<=n; i++)
		{
			for(auto z : w[i])
			{ Tree.modify(1,1,m,x(x(z)),y(x(z)),y(z)); }
			for(auto z : Tree.k(1))
			{
				if(x(z)> x >> y; z = y/2;
			p = lower_bound(res+1,res+1+n,z)-res;
			if(n-p+1>=x)
			{ printf("%lld\n",1ll*x*z*(y-z)); }
			else
			{ printf("%lld\n",1ll*(n-p+1)*z*(y-z)+y*(pre[p-1][0]-pre[n-x][0])-(pre[p-1][1]-pre[n-x][1])); }
		}
		return 0;
	};
}
signed main()
{ return OMA::main(); }

T4

不会,咕...