• 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;
    }
    

      

  • 相关阅读:
    CF516D Drazil and Morning Exercise
    Daily question
    Promise练习
    window.location
    微信二次分享描述变链接,标题也没显示设置的标题,图片也不显示
    Vue项目配置微信分享
    swiper 轮播图圆角滑动变会变成直角然后再回到圆角(iOS)
    IOS下图片不能显示问题的解决办法
    alert组件关闭跳转页面,页面无法滚动(Vue)
    C# .net framework .net core 3.1 请求参数校验, DataAnnotations, 自定义参数校验
  • 原文地址:https://www.cnblogs.com/NanoApe/p/4479318.html
Copyright © 2020-2023  润新知