首页 > 其他分享 >P3997 [SHOI2013]扇形面积并 题解

P3997 [SHOI2013]扇形面积并 题解

时间:2023-02-24 13:44:58浏览次数:43  
标签:cnt ch val int 题解 void fa P3997 SHOI2013

理解题意后可以把题目看成一个覆盖线段的问题。

对于点在 \(-m\) 上,看成在 \(m\) 上。

对于 \(l<r\),不用处理。

对于 \(l>r\),将问题看成 \((l,m)\) 和 \((-m+1.r)\) 两个区间。

对于正常处理点的问题,Splay 可以在 \(l\) 时加入这个点,\(r+1\) 时删除这个点。

但本题为线段覆盖,所以我们可以把线段的下标看为点的下标,但是一个 \((l,r)\) 的区间只能覆盖 \((r-l)\) 的线段数,所以在 \(r\) 时就删除这个点即可。

剩下的都是 Splay 板子了,离线排序,插入,删除,在一个点时判断是否树中有超过 \(k\) 的节点,如果有,那么搜索第 \(k\) 大的数,否则赋为 \(0\)。

时间复杂度:\(O(n\times \log(n))\)。

#include<iostream>
#include<cstdio>
#include<algorithm>
#define int long long
using namespace std;
const int N=1e5+5;
const int M=1e6+5;
int n,m,k,cnt,root,nl,nr;
struct node2
{
	int name,data;
	bool flag;
}ask[4*N];
int cmp2(node2 fi,node2 se)
{
	if(fi.name==se.name)return fi.flag<se.flag;
	return fi.name<se.name;
}
void clac(int &x,int &y)
{
	nl=0;
	if(x>y)
	{
		nl=x;
		x=-m+1;
	}
}
struct node
{
	int fa,ch[2],siz,cnt,val;
}t[4*N];
inline void newnode(int &x,int fa,int val)
{
	x=++cnt;
	t[x].fa=fa;
	t[x].val=val;
	t[x].cnt=t[x].siz=1;
}
inline void connect(int x,int fa,int son)
{
	t[x].fa=fa;
	t[fa].ch[son]=x;
}
inline bool ident(int x,int fa)
{
	return t[fa].ch[1]==x;
}
inline void pushup(int x)
{
	t[x].siz=t[x].cnt+t[t[x].ch[0]].siz+t[t[x].ch[1]].siz;
}
inline void rotate(int x)
{
	int fa=t[x].fa,ff=t[fa].fa,k=ident(x,fa);
	connect(t[x].ch[k^1],fa,k);
	connect(fa,x,k^1);
	connect(x,ff,ident(fa,ff));
	pushup(fa),pushup(x);
}
void splay(int x,int topp=0)
{
	if(topp==0)root=x;
	while(t[x].fa!=topp)
	{
		int fa=t[x].fa,ff=t[fa].fa;
		if(ff!=topp)ident(x,fa)^ident(fa,ff)?rotate(x):rotate(fa);
		rotate(x);
	}
}
void ins(int val,int &x=root,int fa=0)
{
	if(!x)newnode(x,fa,val),splay(x);
	else if(t[x].val>val)ins(val,t[x].ch[0],x);
	else if(t[x].val<val)ins(val,t[x].ch[1],x);
	else t[x].cnt++,splay(x);
}
void erase(int val,int x=root)
{
	if(t[x].val==val)
	{
		splay(x);
		if(t[x].cnt>=2)t[x].cnt--;
		else if(t[x].ch[1])
		{
			int p=t[x].ch[1];
			while(t[p].ch[0])p=t[p].ch[0];
			splay(p,x);	
			root=p,connect(t[x].ch[0],p,0),t[p].fa=0;
			pushup(p);
		}
		else root=t[x].ch[0],t[t[x].ch[0]].fa=0;
	}
	else if(t[x].val>val)erase(val,t[x].ch[0]);
	else erase(val,t[x].ch[1]);
}
int getrank(int k,int x=root)
{
	if(k<=0)
	{
		splay(x);
		return t[x].val;
	}
	if(k<=t[t[x].ch[0]].siz)return getrank(k,t[x].ch[0]);
	int tmp=k-t[t[x].ch[0]].siz-t[x].cnt;
	if(tmp<=0)
	{
		splay(x);
		return t[x].val;
	}
	return getrank(tmp,t[x].ch[1]);
}
signed main()
{
	//freopen("a.out","r",stdin);
	//freopen("area.out","w",stdout);
	scanf("%lld%lld%lld",&n,&m,&k);
	int cnp=0;
	for(int i=1;i<=n;i++)
	{
		int dat,lc,rc;
		scanf("%lld%lld%lld",&dat,&lc,&rc);
		if(lc==-m)lc=m;
		if(rc==-m)rc=m;
		clac(lc,rc);
		ask[++cnp]=(node2){lc,dat,0};
		ask[++cnp]=(node2){rc,dat,1};
		if(nl)ask[++cnp]=(node2){nl,dat,0};
	}
	sort(ask+1,ask+1+cnp,cmp2);
	int bef=1,num=0,ans=0;
	for(int i=-m+1;i<=m;i++)
	{
		for(;bef<=cnp;bef++)
		{
			if(ask[bef].name!=i)break;
			if(ask[bef].flag==1)num--,erase(ask[bef].data*ask[bef].data);
			else num++,ins(ask[bef].data*ask[bef].data);
		}
		if(num>=k)ans+=getrank(num-k+1);
	}
	printf("%lld",ans);
	return 0;
}
/*
10 100 2
24660 98 32
906 -15 -49
26067 -52 -23
15409 -76 -25
22490 41 65
2600 -10 -7
4310 15 75
20389 -100 -3
4421 8 -40
8664 -70 -95
*/

标签:cnt,ch,val,int,题解,void,fa,P3997,SHOI2013
From: https://www.cnblogs.com/gmtfff/p/p3997.html

相关文章

  • P5616 [MtOI2019]恶魔之树 题解
    期望就是来搞笑的。由于有最小公倍数,所以可以想到分解质因数,对于多个数求最小公倍数,取每个质因子的最大指数,最后相乘即可。既然都知道了这个,那么就想到先统计每个数的个......
  • CF10E Greedy Change 题解
    一个非常离谱的题。首先有结论,如果有\(w\)使贪心不为最优解,那么比\(w\)小的第一个\(a_i\),用贪心法求面值为\(a_i-1\),除了最后选的一个数\(a_j\)会比原方法多选一......
  • P2161 [SHOI2009]会场预约 题解
    没事打了个Splay,然后调了3h。觉得题解的找前驱后继与删除复杂了点,主要讲一下这的思路。由于平衡树中每一个点代表的区间互不相交,所有平衡树满足\(l,r\)两个值的BST。......
  • P3224 [HNOI2012]永无乡 题解
    典型Splay练习题。开始建\(n\)个Splay,每一次建边用并查集判断是否在一个子图,不在就合并,即把一个Splay的所有点全插入到另一个Splay中,需要合并的点可以用vector存储。但......
  • P1763 埃及分数 题解
    做完后发现很多题解都是有些细节问题的,对于向上与向下取整非常混乱。第一次做迭代加深搜索的题,记录一下。所谓迭代加深搜索,就是在求搜索树的深度的问题中,枚举层数,取最优......
  • P4048 [JSOI2010]冷冻波 题解
    首先很好想到我们应该预处理出来每一个巫妖王能攻击到的精灵。那么这就是一个几何题。对于每一组精灵与巫妖王,设巫妖王坐标为\((x_1,y_1)\),精灵坐标为\((x_2,y_2)\)。......
  • P7221 [JSOI2010] 蔬菜庆典 题解
    本题解在求无解的情况下优化了下。通过分析样例,我们可以发现如果一个节点有多个Dlihc,那么这些Dlihc对应的权值必须一样,否则可以无限延伸下去。因为一号节点没有Tnera......
  • P3195 [HNOI2008]玩具装箱 题解
    首先先写dp方程非常简单\(\mathit{f}_{i}=\min(\mathit{f}_{j}+(\mathit{c}_{i}+i-j-1-L-\mathit{c}_{j})^2)\)(其中\(\mathit{c}_{i}\)表示长度前缀和)然后发现括号......
  • U259394 Gmt丶FFF 的基环树 题解
    题目链接:传送门之所以评黑,是因为实在是太难调了。(又回调了)。对于有$40%$的数据,$n\le3000$,这部分我们可以暴力删边,然后暴力求直径即可。那么对于$100%$的数据:首先......
  • P3977 [TJOI2015]棋盘 题解
    前制知识引导状态压缩动态规划:[P1896[SCOI2005]互不侵犯](https://www.luogu.com.cn/problem/P1896)矩阵加速优化:[P1962斐波那契数列](https://www.luogu.com.cn/prob......