首页 > 其他分享 >【MX-J3-T3+】Tuple+ 题解

【MX-J3-T3+】Tuple+ 题解

时间:2024-09-27 14:45:57浏览次数:10  
标签:Tuple int 题解 T3 sqrt second MAXN 枚举 first

一个比较自然的思路就是对于每个三元组 \((u_i,v_i,w_i)\),把 \((v_i,w_i)\) 这个二元组放在属于 \(u_i\) 的 vector 里面。然后对于每一个 \(i\in [1,n-3]\),把 \(i\) 的 vector 里面的所有二元组 \((x,y)\) 当作一条连接 \(x,y\) 的无向边,则我们的目的是在图中找出所有的三元环 \((p_1,p_2,p_3)\),如果这个三元组被给出了,我们就让它与 \(i\) 组成一个合法的四元组 \((i,p_1,p_2,p_3)\)(\(i<p_1<p_2<p_3\))。

无向图找三元环的话就是一个比较模板的题目了。我们考虑给每条无向边定向,对于 \((x,y)\) 这条边,设 \(d_i\) 表示 \(i\) 的度数,若 \(d_x>d_y\) 或者 \(d_x=d_y\wedge x>y\),我们就定向为 \(x\to y\)。

然后我们就枚举每一个点 \(x\),然后枚举 \(x\) 指向的某个点 \(y\),再枚举 \(y\) 指向的另一个点 \(z\),若 \((x,z)\) 存在连边,则 \((x,y,z)\) 构成一个三元环。时间复杂度可以分类讨论证明一下:设边数为 \(M\),若 \(d_x\leq \sqrt{M}\),则 \(d_z\leq d_y\leq d_x\leq \sqrt{M}\),那么此次枚举就是 \(O(\sqrt{M})\) 的;若 \(d_x>\sqrt{M}\),则此次枚举最劣是 \(O(M)\) 的,而度数大于 \(\sqrt{M}\) 的点最多只有 \(\sqrt{M}\) 个,所以综合起来的复杂度就是 \(O(M\sqrt{M})\)。

由此,我们可以在规定的时间内找出所有的三元环,接着判一下每个三元环是否被给出即可。这里最好是先找完所有三元环,然后再一次性的挨个判断,不然判断时的 \(O(\log m)\) 可能会堆积在 \(O(M\sqrt{M})\) 这个时间复杂度上。

对于我们枚举的 \(i\),设其 vector 中存了 \(M_i\) 条边,则有 \(\sum M_i=m\),我们的总时间复杂度为 \(O(\sum M_i\sqrt{M_i})\)。

结论:\(a\sqrt{a}+b\sqrt{b}<(a+b)\sqrt{a+b}\),其中 \(a,b>0\)。

证明:将两边同时平方可得 \(a^3+b^3+2ab\sqrt{ab}<a^3+b^3+3ab^2+3a^2b\)。去掉相同项就能化简为 \(\sqrt{ab}<1.5(a+b)\),根据均值不等式 \(a+b\geq 2\sqrt{ab}\) 即可证明 \(\sqrt{ab}<1.5(a+b)\) 成立。

拓展一下这个结论可以知道 \(\sum M_i\sqrt{M_i}< (\sum M_i)\sqrt{\sum M_i}=m\sqrt{m}\)。因此我们的最劣时间复杂度为 \(O(m\sqrt{m})\)。

代码如下:

#include<bits/stdc++.h>
using namespace std;
const int MAXN=3e5+5;
int n,m;
int u[MAXN],v[MAXN],w[MAXN];
vector<pair<int,int> > vec[MAXN];
int stk[MAXN<<1],cnt;
int in[MAXN];
int head[MAXN],nxt[MAXN<<1],to[MAXN<<1],tot;
void add(int x,int y)
{
	to[++tot]=y;
	nxt[tot]=head[x];
	head[x]=tot;
}
vector<int> v1[MAXN];
int vis[MAXN];
map<pair<pair<int,int>,int>,int> mp;
vector<pair<pair<int,int>,int> > temp;
int main()
{
	cin>>n>>m;
	for(int i=1;i<=m;i++)	cin>>u[i]>>v[i]>>w[i],vec[u[i]].push_back(make_pair(v[i],w[i]));
	int res=0;
	for(int s=1;s<=n-3;s++)
	{
		if(!vec[s].size())	continue;
		cnt=0,tot=0;
		for(auto j:vec[s])	stk[++cnt]=j.first,stk[++cnt]=j.second,add(j.first,j.second),add(j.second,j.first);
		for(auto j:vec[s])	in[j.first]++,in[j.second]++;
		sort(stk+1,stk+cnt+1),cnt=unique(stk+1,stk+cnt+1)-stk-1;
		for(int i=1;i<=cnt;i++)
		{
			for(int j=head[stk[i]];j;j=nxt[j])
			{
				if(in[stk[i]]>in[to[j]]||in[stk[i]]==in[to[j]]&&stk[i]>to[j])	v1[stk[i]].push_back(to[j]);
			}
		}
		temp.clear();
		for(int i=1;i<=cnt;i++)
		{
			for(int j:v1[stk[i]])	vis[j]=1;
			for(int j:v1[stk[i]])
			{
				for(int k:v1[j])
				{
					if(vis[k])	temp.push_back(make_pair(make_pair(stk[i],j),k));
				}
			}
			for(int j:v1[stk[i]])	vis[j]=0;
		}
		for(auto j:temp)
		{
			if(j.first.first>j.first.second)	swap(j.first.first,j.first.second);
			if(j.first.second>j.second)	swap(j.first.second,j.second);
			if(j.first.first>j.first.second)	swap(j.first.first,j.first.second);
			mp[j]++;
		}
		for(int i=1;i<=cnt;i++)	head[stk[i]]=0,in[stk[i]]=0,v1[stk[i]].clear();
	}
	for(int i=1;i<=m;i++)	res+=mp[make_pair(make_pair(u[i],v[i]),w[i])];
	cout<<res;
	return 0;
}

标签:Tuple,int,题解,T3,sqrt,second,MAXN,枚举,first
From: https://www.cnblogs.com/SuporShoop/p/18435707

相关文章

  • [ARC115E] LEQ and NEQ 题解
    我这场打的VP,结果E思考的时间比A还少。。但是我觉得我能想出这道题还是很有意义的,写篇题解记录一下。首先应该都不难想到动态规划吧?我们先使用暴力DP:设\(dp_{i,j}\)表示处理完前\(i\)个数,第\(i\)个数为\(j\)的方案数。我们考虑进行分类讨论:\(a_i≥a_{i-1}\):此时......
  • 9.27今日错题解析(软考)
    目录前言信息安全——网络攻击算法基础——二分查找数据库系统——数据库设计过程前言这是用来记录我每天备考软考设计师的错题的,今天知识点为网络攻击、二分查找和数据库设计过程,大部分错题摘自希赛中的题目,但相关解析是原创,有自己的思考,为了复习:),最后希望各位报考......
  • [GXOI/GZOI2019] 逼死强迫症 题解
    看到\(N\leq2\times10^9\)的范围,一眼矩阵快速幂优化DP。首先考虑朴素DP怎么写。根据题目所给信息,我们设\(dp_{i,0}\)表示前面\(i\)个方砖,并且已经使用了\(2\)个\(1\times1\)的方砖,\(dp_{i,1}\)则表示前面\(i\)个方砖,没有使用任何一个\(1\times1\)的方砖。......
  • [CERC2015] Digit Division 题解
    \(O(n^2)\)做法和大部分人最开始一样,我也想的是DP。设\(dp_i\)表示用前面\(i\)个字符拆分得到的答案。既然是统计方案数,我们肯定是根据前面的答案累加。考虑在\([1,i-1]\)中选择一个\(j\),如果\([j+1,i]\)的字符组成的数字能够被\(m\)整除,那么\(dp_i\)就可以累加......
  • [JLOI2015] 有意义的字符串 题解
    拿到题目,我们首先分析一下这个奇怪的式子:\[\lfloor(\frac{b+\sqrt{d}}{2})^n\rfloor~\text{mod}~p\]重点肯定是在里面的那个式子里面,最显眼的肯定也就是那个\(\sqrt{d}\),根据整体形式,我们可以联系一元二次方程的求根公式\(x=-\dfrac{-b\pm\sqrt{b^2-4ac}}{2a}\),这里也是一......
  • 「KDOI-06-S」消除序列 题解
    分享一个应该很少人想到的做法。首先贪心地想,第一种操作肯定最多选择一次。比如如果选择了下标\(i\)和\(j\)进行第一种操作,那么就等价于在\(\max\{i,j\}\)进行了一次操作。由于代价是非负数,则我们最多只用执行一次。当然也可以不使用这种操作。有了这个思路,我们先考虑不使......
  • 「TAOI-2」Ciallo~(∠・ω< )⌒★ 题解
    手玩了一个小时终于做出来了,这不得写一篇题解记录一下??下面设\(s\)的长度为\(n\),\(t\)的长度为\(m\)。考虑分类讨论:如果\(s\)中有一个子串\(s'\)与\(t\)完全相同(可以用哈希进行比较),设\(s'\)是\(s\)的第\(l\)到第\(r\)个字符组成的字符串,则我们可以删除\([1,......
  • 三星G8 OLED显示器S34BG850SC,使用DP线连接电脑,显示器黑屏问题解决。
    这个问题在网上好像很多人问,但是每个人的情况不同,总之我也是遇到了。事情大概:PC机显卡的DP口通过显示器自带的MiniDP线和显示器相连,这个没什么好说的了,原配只送MiniDP线,想必买这台显示器的人都是先用的这根线。然而我有一台NUC,通过雷电口也连接到了这台显示器。所以我这台G8是......
  • [TJOI2010] 天气预报 题解
    分析一下题目,大致意思就是给定一组常数\(a_i\),然后有一个递推式\(w_i=\sum_{j=1}^{n}w_{i-j}\timesa_{j}\),让你求出\(w_m\)对于\(4147\)取模的值。根据这个\(1\leqm\leq10^7\)的恐怖范围,姑且算到了\(O(m)\)的时间复杂度。但是观察一下这个递推式,发现\(O(m)\)跑......
  • ABC262G 题解
    LISwithStack观察到\(n\le50\),考虑区间dp。设\(dp(l,r,x,y)\)表示区间\([l,r]\)中选出的子序列的最小值\(\gex\),最大值\(\ley\)的方案数。根据栈的性质,设元素\(x\)入栈的时间为\(in_x\),出栈时间为\(out_x\),那么所有元素构成的区间\([in_x,out_x]\)两......