1. 程式人生 > 實用技巧 >【LGR-073】洛谷 7 月月賽 Div.2 題解

【LGR-073】洛谷 7 月月賽 Div.2 題解

因為我太弱,所以只做了Div.2。


T1:

就這還要題解?

暴力列舉,慢走。


T2:

假設腰長為\(b\),底邊長為\(c\)

顯然\(b+c>b\)恆成立。

所以只要\(b+b>c\)即可。

\(0 < c < 2b\)

用桶來統計一遍,再在桶上套一個字首和。

\(i\)出現了\(buc_i\)次,字首和為\(sum_i\)

對於腰長為\(b\)的情況,分兩種:

一、非等邊:在當前長度為\(b\)的棍子中選兩個,再在不為\(b\)\(< 2b\)的裡面選\(1\)個。

\(\binom{buc_i}{2} \left ( sum_{2i-1}-buc_i \right )\)

種情況。

二、等邊:在長度為\(b\)的棍子中選三個。

\(\binom{buc_i}{3}\)種情況。

列舉\(b\),兩種情況加起來,再模\(998244353\)

code:

#include<bits/stdc++.h>
using namespace std;
const int mod=998244353;
int a[200005];int buc[200005];int sum[200005];
int main()
{
	int n;cin>>n;
	for(int i=1;i<=n;++i)
	{
		cin>>a[i];++buc[a[i]];
	}
	for(register int i=1;i<=200000;++i)
	{
		sum[i]=sum[i-1]+buc[i];
	}
	long long ans=0;
	for(register int i=1;i<=200000;++i)
	{
		if(buc[i]>1)
		{
			long long bdb=1ll*buc[i]*(buc[i]-1)/2%mod*(sum[min(((i<<1)-1),200000)]-buc[i]);
			long db=1ll*buc[i]*(buc[i]-1)*(buc[i]-2)/6%mod;
			(ans+=(bdb+db)%mod)%=mod;
		}
	}
	cout<<ans%mod<<endl;
	return 0;
}

T3:

需要稍微思考一下。

看到唯一的操作,先轉一個\(2 \times 2\)的區域。

容易發現:同一列的數字永遠在一起

然後,一列的書每移動一下,就會上下顛倒。

容易發現:一列數字,移動奇數次則上下顛倒,否則不變

所以就很好判定有無解了。

那怎樣判定移動次數呢?

我們可以把一列看成一個數。

坑待填。