zoukankan      html  css  js  c++  java
  • 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
    ", Query(q[i][1], q[i][2], q[i][3]));
    	return 0;
    }
    

      

  • 相关阅读:
    iOS开发-UIScrollView原理
    关于tableView点击状态栏列表回到顶部的说明
    实用技术之bugly
    KVO你所不知道的"坑"
    iOS iPhone SDK 包含哪些东西?
    NSTime的全面认识
    四 数据结构与算法总结(一)
    三 数据结构 --数和二叉树
    二 线性表
    一 数据结构的概念,时间复杂度和空间复杂度
  • 原文地址:https://www.cnblogs.com/NanoApe/p/4479318.html
Copyright © 2011-2022 走看看