首页 > 其他分享 >P4062 Yazid 的新生舞会

P4062 Yazid 的新生舞会

时间:2024-07-30 18:06:52浏览次数:5  
标签:舞会 int ++ mid Yazid P4062 num maxn 众数

谨以此文纪念一场灾难

来给这位善良的人的人点点赞

题面
image


题解:

首先 题面中所指的众数为 绝对众数(绝对众数是指在一组数据中出现次数 \(超过\) 总数一半的数值。), 下文的所有众数也指绝对众数。

有以下性质

  • 任意一个区间的绝对众数的数值唯一

  • 如果\(x\)是区间\([l,r]\)的众数,那么对于\(l≤k≤r\),\(x\)一定是区间\([l,k]\)或区间\((k,r]\)的众数。

  • 以 \(n\) 结尾的所有区间的绝对众数构成的集合大小不超过为 \(log⁡n\)

一 ( \(O(nlog^{2}n)\) 做法) :

因为众数个数的取值范围极小,且又有性质二可以利用,考虑分治做法:

对于每个区间 \([L,R]\) ,取 \(mid=(l+r)/2\) ,并将\(mid\) 设为性质二中的\(k\),以此求出所有可能的众数,并记录.

对于每个过 \(mid\) 的小区间 \([l,r]\) ,只有当存在众数 \(v\) 使得 \([l,r]\) 间的 \(sum_{v}\gt\frac{r-l+1}{2}\) ,才可使\(ans++\).

又因为C++中自动向下取整 ,所以对 \(r-l+1\) 的奇偶性分讨 得

\[sum_{v}\gt \lfloor\frac{r-l+1}{2} \rfloor\Leftrightarrow 2sum_{v}\ge r-l+2 \]

设\(v\)在\([l,mid]\)的个数为 \(Sl\) ,\([mid+1,r]\) 为 \(Sr\)。
因为 \(sum_{v}=Sl+Sr\).
所以

\[l+2Sl\ge r-2Sr+2\tag{1} \]

所以对于每个\([L,R]\)中的\(l,r\)都有一一对应的\(l+2Sl,r-2Sr\).

因此可以预先处理出每个\(l\) 对应的$l+2Sl $ 值, 并储存起来。

然后对于每个\(r\),找出所有找出满足\((1)\) 的 \(l\)的个数(用求后缀的方式),并计入\(ans\).

最后向下一层递归,本题就结束了.

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=5e5+10;
int a[maxn],cnt[maxn],num[maxn],pos[maxn],c[maxn];
"""
cnt[]表示 值为l+Sl的个数
"""
int ans=0;
void sol(int l,int r)
{
	if(l==r)
	{
		ans++;
		return;
	}		
	int mid=(l+r)>>1;
	sol(l,mid);
	sol(mid+1,r);
	
	for(int i=l;i<=mid;++i)
		if(++cnt[a[i]]>=(mid-i+1)/2 and !pos[a[i]])	
			num[pos[a[i]]=++num[0]]=a[i];
	
	for(int i=l;i<=mid;++i)
		cnt[a[i]]=0;
	
	for(int i=mid+1;i<=r;++i)
		if(++cnt[a[i]]>=(i-mid)/2 and !pos[a[i]])
			num[pos[a[i]]=++num[0]]=a[i];
		
	for(int i=l;i<=r;++i)
		cnt[a[i]]=pos[a[i]]=0;
		
	for(int j=1,v;v=num[j],j<=num[0];++j)
	{
		int L=1e9,R=0;
		
		for(int i=mid,t=0;i>=l;--i)
		{
			if(a[i]==v)t+=2;
			++c[t+i];
			
			L=min(L,t+i);
			R=max(R,t+i);
		}
		
		for(int i=R;i>=L;--i)
			c[i]+=c[i+1];
		
		int tmp=0;
		for(int i=mid+1,t=0;i<=r;++i)
		{
			if(a[i]==v)t+=2;
			tmp+=c[max(L,i-t+2)];
		}
		ans+=tmp;
		
		for(int i=L;i<=R;++i)
			c[i]=0;
	}
	
	num[0]=0;
}

signed main()
{
	//freopen("in.in","r",stdin);
	//freopen("out.out","w",stdout);
	int n,x;
	cin>>n;
	cin>>x;
	for(int i=1;i<=n;++i) cin>>a[i];
	sol(1,n);
	cout<<ans;
	return 0;
}


标签:舞会,int,++,mid,Yazid,P4062,num,maxn,众数
From: https://www.cnblogs.com/CTHoi/p/18333081

相关文章

  • [树形dp]没有上司的舞会
    题目描述UralUralUral大学有N......
  • 舞会无领导:一种树形动态规划的视角
    没有上司的舞会Ural大学有......
  • 树形DP——AcWing 285. 没有上司的舞会
    目录树形DP定义运用情况注意事项解题思路AcWing285.没有上司的舞会 题目描述运行代码代码思路改进思路改进代码(AI)其它代码代码思路树形DP定义树形DP是在树上进行的动态规划。它利用树的结构特点,通过递归或迭代的方式,在每个节点上进行状态计算和转移,以求......
  • 洛谷 P1352 没有上司的舞会
    题目链接:没有上司的舞会思路题解#include<bits/stdc++.h>usingnamespacestd;#definelllonglongconstintN=1e5+10;intdp[N][2],happy[N],subordinate[N],cnt,head[N],nex[N],edge[N];//链式向前星存储边voidadd(intx,inty){nex[++cnt]=......
  • P1352 没有上司的舞会
    链接:https://www.luogu.com.cn/problem/P1352树形dp板子,感觉很巧妙,利用01表示是否取代码:#include<iostream>#include<vector>#include<algorithm>#include<math.h>#include<sstream>#include<string>#include<string.h>#include<iom......
  • 树形DP->没有上司的舞会(洛谷1352)
    题意:每个人有一个happ值,n个人,n-1条有向边,u是v的上司,求happy值最大。限制条件是u和v不能同时参加。分析:没想到一个v居然有很多上司,更没想到n-1条边居然是个森林。//没想到,一个员工居然可以有那么多上司。。voidsolve(){intn;cin>>n;vector<int>happy(n......
  • 【题解 P4062 & P8313】 Yazid 的新生舞会&Izbori
    [COCI2021-2022#4]Izbori题目描述Malnar先生正在竞选县长,这个县一共有\(n\)栋房屋,每栋房屋里都住着一位居民。Malnar先生知道,选举的赢家不一定是最好的候选人,而是在选举前举办的宴会最好的候选人。因此,在选举前几天,他将邀请第\(l\)至\(r(l\ler)\)栋房屋内居住的居民,为......
  • P4062 [Code+#1] Yazid 的新生舞会
    题外话我记得第一次看见这道题是几个月前刚开始集训的时候,当时一点思路都没有,但是今天自己做出来了,很喜欢这种感觉!\(\text{Links}\)原题传送门可能更好的阅读体验题意求给定序列中有多少个子区间满足众数出现次数严格大于区间长度的一半。题解题目要求满足条件的子区间......
  • P1352 没有上司的舞会
    考察算法:树形\(DP\)。题目概述给你一个树,每个结点有一个“上司”。每个节点都有一个快乐指数\(h_i\)。但是,如果有某个节点的上司(父亲),已经来到了舞会,那么它的儿子就不能去了。求:最大的快乐指数(所有人的快乐指数之和)。思路树形\(DP\)。设\(f_{i,0}\)表示以\(i\)作为......
  • Luogu P1352没有上司的舞会
    分析树形dp。定义状态\(dp_{~i,~0}\)为在以\(i\)为根节点的子树中,不选第\(i\)个人的最大快乐值,\(dp_{~i,~1}\)为在以\(i\)为根节点的子树中,选第\(i\)个人的最大快乐值。寻找根节点,然后从根节点开始dfs,当前节点\(u\)的\(dp\)初始状态为\(dp_{~i,~0}=0,~dp_{~i......