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)
    

      

  • 相关阅读:
    Android 适配知识点
    Android Studio各种快捷功能及好用的插件
    81.Android之沉浸式状态栏攻略
    8.Android 系统状态栏沉浸式/透明化解决方案
    为开发者准备的 Android 函数库(2016 年版)
    GitHub 上 57 款最流行的开源深度学习项目
    7.Android开源项目WheelView的时间和地址联动选择对话框
    6.初探Asynctask
    5.Android消息推送机制简单例子
    让你Android开发更简单
  • 原文地址:https://www.cnblogs.com/Gloid/p/10624878.html
Copyright © 2011-2022 走看看