BZOJ-2829 信用卡凸包

凸包题。

我们先把所有信用卡的四个定点的坐标求出来,然后计算凸包长度,最后加上一个圆的周长就行。

#include <cstdlib>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#define rep(i, l, r) for(int i=l; i<=r; i++)
#define clr(x, c) memset(x, c, sizeof(x))
#define lowbit(x) (x&-x)
#define maxn 10009
#define maxm 20009
#define inf 0x7fffffff
#define k(x) Key[x]
#define t(x) Tree[x]
using namespace std;
inline int read()
{
	int x=0, f=1; char ch=getchar();
	while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
	while (isdigit(ch)) x=x*10+ch-'0', ch=getchar();
	return x*f;
}
struct node{node *l, *r; int sum;} *blank=new(node), *Tree[maxn], *r1[maxn], *r2[maxn];
struct node2{int v, n;} num[maxm];
bool cmp(node2 a, node2 b){return a.v<b.v;}
int n, m, V, q[maxn][4], Key[maxm], ln, n1, n2, c[maxm];
char ch[5];
void Build(int l, int r, node*&t)
{
	if (t==blank) t=new(node), t->l=t->r=blank, t->sum=0;
	if (l==r) return;
	int mid=(l+r)>>1;
	Build(l, mid, t->l), Build(mid+1, r, t->r);
}
void Add(int k, int y, int l, int r, node *u, node*&t)
{
	if (t==blank) t=new(node), t->l=t->r=blank, t->sum=0;
	t->sum=u->sum+y;
	if (l==r) return; int mid=(l+r)>>1;
	if (k<=mid)
		t->r=u->r, Add(k, y, l, mid, u->l, t->l);
	else
		t->l=u->l, Add(k, y, mid+1, r, u->r, t->r);
}
inline void Change(int t, int k)
{
	node *p; int v=k(t); k(t)=k;
	for(int x=t; x<=n; x+=lowbit(x))
		Add(v, -1, 1, ln, t(x), p=blank), t(x)=p;
	for(int x=t; x<=n; x+=lowbit(x))
		Add(k, 1, 1, ln, t(x), p=blank), t(x)=p;
}
inline int Query(int l, int r, int k)
{
	n1=n2=0; k--;
	for(int x=l-1; x; x-=lowbit(x)) r1[++n1]=t(x);
	for(int x=r; x; x-=lowbit(x)) r2[++n2]=t(x);
	int L=1, R=ln;
	while (L<R)
	{
		int sum=0, mid=(L+R)>>1;
		rep(j, 1, n1) sum-=r1[j]->l->sum;
		rep(j, 1, n2) sum+=r2[j]->l->sum;
		if (sum<=k)
		{
			L=mid+1, k-=sum;
			rep(j, 1, n1) r1[j]=r1[j]->r;
			rep(j, 1, n2) r2[j]=r2[j]->r;
		}
		else
		{
			R=mid;
			rep(j, 1, n1) r1[j]=r1[j]->l;
			rep(j, 1, n2) r2[j]=r2[j]->l;
		}
	}
	return c[L];
}
void Init(){blank->l=blank->r=blank; blank->sum=0;}
int main()
{
	n=V=read(), m=read(); Init();
	rep(i, 1, n) num[i].v=read(), num[i].n=i; 
	rep(i, 1, m)
	{
		scanf("%s", ch);
		if (ch[0]=='Q') 
			q[i][0]=1, q[i][1]=read(), q[i][2]=read(), q[i][3]=read();
		else
		{
			q[i][0]=0, q[i][1]=read(), q[i][2]=read();
			++V, num[V].v=q[i][2], num[V].n=n+i;
		}
	}
	sort(num+1, num+V+1, cmp);
	c[++ln]=num[1].v, k(num[1].n)=1;
	rep(i, 2, V)
	{
		if (num[i].v != num[i-1].v) c[++ln]=num[i].v;
		k(num[i].n)=ln;
	}
	Build(1, ln, t(0)=blank);
	rep(i, 1, n)
	{
		node *p=t(0);
		rep(j, i-lowbit(i)+1, i)
			Add(k(j), 1, 1, ln, p, t(i)=blank), p=t(i);
	}
	rep(i, 1, m)
		if (!q[i][0]) Change(q[i][1], k(n+i));
		else printf("%d\n", Query(q[i][1], q[i][2], q[i][3]));
	return 0;
}

  

posted @ 2015-05-05 15:43  NanoApe  阅读(405)  评论(0编辑  收藏  举报
AmazingCounters.com