zoukankan      html  css  js  c++  java
  • BZOJ2658 ZJOI2012 小蓝的好友(treap)

      显然转化为求不包含关键点的矩形个数。考虑暴力,枚举矩形下边界,求出该行每个位置对应的最低障碍点高度,对其建笛卡尔树,答案即为Σhi*(slson+1)*(srson+1),即考虑跨过该位置的矩形个数。

      笛卡尔树就是treap,于是考虑利用treap将其动态维护,将hi设为treap的优先级。移动下边界,可以发现每次相当于将所有点的优先级+1,并对该行出现的关键点将对应位置的优先级设为0,打打标记瞎维护下即可。由于数据随机复杂度很对。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define ll long long
    #define N 100010
    #define lson tree[k].ch[0]
    #define rson tree[k].ch[1]
    char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
    int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
    int read()
    {
    	int x=0,f=1;char c=getchar();
    	while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
    	while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return x*f;
    }
    int n,r,c,root,cnt;
    ll ans;
    struct data
    {
    	int x,y;
    	bool operator <(const data&a) const
    	{
    		return x<a.x;
    	}
    }a[N];
    struct data2{int ch[2],x,p,s,lazy;ll ans;
    }tree[N<<1];
    void up(int k)
    {
    	tree[k].s=tree[lson].s+tree[rson].s+1;
    	tree[k].ans=tree[lson].ans+tree[rson].ans+1ll*tree[k].p*(tree[lson].s+1)*(tree[rson].s+1);
    }
    void move(int &k,int p)
    {
    	int t=tree[k].ch[p];
    	tree[k].ch[p]=tree[t].ch[!p],tree[t].ch[!p]=k,up(k),up(t),k=t;
    }
    void build(int &k,int l,int r)
    {
    	if (l>r) return;
    	k=++cnt;
    	int mid=l+r>>1;
    	tree[k].x=mid,tree[k].p=0;
    	build(lson,l,mid-1);
    	build(rson,mid+1,r);
    	up(k);
    }
    void update(int k,int x)
    {
    	tree[k].lazy+=x;
    	tree[k].p+=x;
    	tree[k].ans+=1ll*x*tree[k].s*(tree[k].s+1)/2;
    }
    void down(int k)
    {
    	update(lson,tree[k].lazy);
    	update(rson,tree[k].lazy);
    	tree[k].lazy=0;
    }
    void modify(int &k,int x)
    {
    	down(k);
    	if (tree[k].x==x) tree[k].p=0;
    	else if (tree[k].x<x) modify(rson,x),move(k,1);
    	else modify(lson,x),move(k,0);
    	up(k);
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
    	freopen("bzoj2658.in","r",stdin);
    	freopen("bzoj2658.out","w",stdout);
    	const char LL[]="%I64d
    ";
    #else
    	const char LL[]="%lld
    ";
    #endif
    	r=read(),c=read(),n=read();
    	for (int i=1;i<=n;i++) a[i].x=read(),a[i].y=read();
    	ans=1ll*r*(r+1)*c*(c+1)/4;
    	sort(a+1,a+n+1);
    	build(root,1,c);
    	int x=0;
    	for (int i=1;i<=r;i++)
    	{
    		update(root,1);
    		while (a[x+1].x==i)
    		{
    			x++;
    			modify(root,a[x].y);
    		}
    		ans-=tree[root].ans;
    	}
    	cout<<ans;
    	return 0;
    }
    //ans=Σpi*(sl+1)*(sr+1)
    

      

  • 相关阅读:
    mysql教程(九) 索引详解
    mysql教程(八) 事务详解
    mysql教程(七) 约束详解
    mysql教程(七)创建表并添加约束
    mysql教程(六) 对字段的操作--添加、删除、修改
    mysql教程(五)limit的用法
    mysql教程(四)连接查询
    mysql教程(三)分组查询group by
    mysql教程(一)count函数与聚合函数
    mysql教程(二)数据库常用函数汇总
  • 原文地址:https://www.cnblogs.com/Gloid/p/10624878.html
Copyright © 2011-2022 走看看