zoukankan      html  css  js  c++  java
  • 【BZOJ2658】[Zjoi2012]小蓝的好友(mrx) 平衡树维护笛卡尔树+扫描线

    【BZOJ2658】[Zjoi2012]小蓝的好友(mrx)

    Description

    终于到达了这次选拔赛的最后一题,想必你已经厌倦了小蓝和小白的故事,为了回馈各位比赛选手,此题的主角是贯穿这次比赛的关键人物——小蓝的好友。
    在帮小蓝确定了旅游路线后,小蓝的好友也不会浪费这个难得的暑假。与小蓝不同,小蓝的好友并不想将时间花在旅游上,而是盯上了最近发行的即时战略游戏——SangoCraft。但在前往通关之路的道路上,一个小游戏挡住了小蓝的好友的步伐。
    “国家的战争其本质是抢夺资源的战争”是整款游戏的核心理念,这个小游戏也不例外。简单来说,用户需要在给定的长方形土地上选出一块子矩形,而系统随机生成了N个资源点,位于用户所选的长方形土地上的资源点越多,给予用户的奖励也越多。悲剧的是,小蓝的好友虽然拥有着极其优秀的能力,但同时也有着极差的RP,小蓝的好友所选的区域总是没有一个资源点。
    终于有一天,小蓝的好友决定投诉这款游戏的制造厂商,为了搜集证据,小蓝的好友想算出至少包含一个资源点的区域的数量。作为小蓝的好友,这自然是你分内之事。

    Input

     每个输入文件中仅包含一个测试数据。
    第一行包含两个由空格隔开的正整数R,C,N,表示游戏在一块[1,R]X[1,C]的地图上生成了N个资源点。
         接下来有N行,每行包含两个整数 x,y,表示这个资源点的坐标
    (1<=x<=R,1<=Y<=c)。

    Output

          输出文件应仅包含一个整数,表示至少包含一个资源点的区域的数量。具体的说,设N个资源点的坐标为(i=1..n),你需要计算有多少个四元组(LB,DB,RB,UB)满足1<=LB<=RB<=R,1<=DB<=UB<=C,且存在一个i使得LB<=Xi<=RB,DB<=Yi<=UB均成立

    Sample Input

    5 5 4
    1 2
    2 3
    3 5
    4 1

    Sample Output

    139

    HINT

    【数据范围】
    对于100%的数据,R,C<=40000,N<=100000,资源点的位置两两不同,且位置为随机生成。

    题解:第一思路一定是补集转化,我们改求不包含黑点的矩形个数。然后考虑枚举矩形的底边所在行,考虑这一行的贡献是什么。

    我们将这一行中,每一列上面遇到的第一个黑点到这一行的距离定义为这一列的高度。然后我们对这一行中,所有列的高度建出一棵笛卡尔树。假设树上第i个节点的子树大小是siz[i],高度是h[i],那么这个点对答案的贡献就是${siz imes (siz+1) over 2} imes(h[i]-h[fa])$。

    这样做的复杂度是O(Rn)的。但是我们发现数据是随机的,随机数据有什么性质?随机序列的笛卡尔树的树高是O(logn)的,并且笛卡尔树其实是一棵Treap!所以我们可以考虑用Treap维护笛卡尔树。当我们向下平移一行时,首先所有点的高度+1,这个打标记就好;然后这一行可能冒出来一些黑点,我们将这些黑点旋转上来,然后将高度变成0即可。我们还要动态维护一下所有点的${siz imes (siz+1) over 2} imes(h[i]-h[fa])$,这个比较麻烦,需要注意一下细节。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <vector>
    using namespace std;
    const int maxn=100010;
    typedef long long ll;
    vector<int> px[maxn];
    vector<int>::iterator it;
    ll ans;
    int R,C,n,rt;
    struct node
    {
    	int ch[2],siz,fa,h,tag;
    	ll sum;
    }s[maxn];
    inline ll c(const ll &x) {return x*(x+1)>>1;}
    inline void add(int x,int y) {s[x].h+=y,s[x].tag+=y;}
    inline void pushdown(int x)
    {
    	if(s[x].tag)
    	{
    		if(s[x].ch[0])	add(s[x].ch[0],s[x].tag);
    		if(s[x].ch[1])	add(s[x].ch[1],s[x].tag);
    		s[x].tag=0;
    	}
    }
    inline void pushup(int x)
    {
    	s[x].siz=s[s[x].ch[0]].siz+s[s[x].ch[1]].siz+1;
    	s[x].sum=s[s[x].ch[0]].sum+s[s[x].ch[1]].sum+c(s[x].siz)*(s[x].h-s[s[x].fa].h);
    }
    void updata(int x)
    {
    	if(x!=rt)	updata(s[x].fa);
    	pushdown(x);
    }
    inline void rotate(int x)
    {
    	int y=s[x].fa,z=s[y].fa,d=(x==s[y].ch[1]);
    	if(y==rt)	rt=x;
    	else	s[z].ch[y==s[z].ch[1]]=x;
    	s[x].fa=z,s[y].fa=x,s[y].ch[d]=s[x].ch[d^1];
    	if(s[x].ch[d^1])	s[s[x].ch[d^1]].fa=y,pushdown(s[x].ch[d^1]),pushup(s[x].ch[d^1]);
    	s[x].ch[d^1]=y;
    	pushup(y),pushup(x);
    }
    int build(int l,int r)
    {
    	if(l>r)	return 0;
    	int x=(l+r)>>1;
    	s[x].ch[0]=build(l,x-1),s[x].ch[1]=build(x+1,r),s[x].siz=r-l+1;
    	if(s[x].ch[0])	s[s[x].ch[0]].fa=x;
    	if(s[x].ch[1])	s[s[x].ch[1]].fa=x;
    	return x;
    }
    inline int rd()
    {
    	int ret=0,f=1;	char gc=getchar();
    	while(gc<'0'||gc>'9')	{if(gc=='-')	f=-f;	gc=getchar();}
    	while(gc>='0'&&gc<='9')	ret=ret*10+(gc^'0'),gc=getchar();
    	return ret*f;
    }
    int main()
    {
    	R=rd(),C=rd(),n=rd();
    	int i,a,b;
    	for(i=1;i<=n;i++)	a=rd(),b=rd(),px[b].push_back(a);
    	rt=build(1,R);
    	for(i=C;i>=1;i--)
    	{
    		add(rt,1),pushup(rt);
    		for(it=px[i].begin();it!=px[i].end();it++)
    		{
    			a=*it,updata(a);
    			while(a!=rt)	rotate(a);
    			s[a].h=0;
    			if(s[a].ch[0])	pushdown(s[a].ch[0]),pushup(s[a].ch[0]);
    			if(s[a].ch[1])	pushdown(s[a].ch[1]),pushup(s[a].ch[1]);
    			pushup(a);
    		}
    		ans+=s[rt].sum;
    	}
    	printf("%lld",c(R)*c(C)-ans);
    	return 0;
    }
  • 相关阅读:
    1012 The Best Rank (25 分)(排序)
    1011. World Cup Betting (20)(查找元素)
    1009 Product of Polynomials (25 分)(模拟)
    1008 Elevator (20 分)(数学问题)
    1006 Sign In and Sign Out (25 分)(查找元素)
    1005 Spell It Right (20 分)(字符串处理)
    Kafka Connect 出现ERROR Failed to flush WorkerSourceTask{id=local-file-source-0}, timed out while wait
    flume、kafka、avro组成的消息系统
    Java23种设计模式总结【转载】
    Java编程 思维导图
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/8142697.html
Copyright © 2011-2022 走看看