欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

King Gym - 102471H

发布时间:2023/12/3 62 豆豆
生活随笔 收集整理的这篇文章主要介绍了 King Gym - 102471H 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

King Gym - 102471H

题意:

给你一个数组b,让你找到一个最长的最长的king子序列,如果长度大于等于n/2,输出长度值,否则输出-1
一个序列(a1,a2,...,an)(a_{1},a_{2},...,a_{n})(a1,a2,...,an)是king序列当且仅当存在一个整数q,1<=q<p,对于所有的i∈[2,n],qai−1≡ai(modp)qa_{i-1}≡a_{i}(\mod p)qai1ai(modp)

题解:

qai−1≡ai(modp)qa_{i-1}≡a_{i}(\mod p)qai1ai(modp)这个式子可以理解为在模p意义下找到一个最长的等比数列,q是多少不知道
题目有个特殊性质,如果长度大于等于n/2,输出长度值,小于输出-1。当答案超过n/2时,说明有一半以上的数都参与了king子序列的组成,也就说说子序列中相邻两个数在原序列中不会距离太远,一定会有两个数相邻或者紧靠着
我们随机在序列最终随机取两个数,这两个数出现在序列中的可能性大于1/4((1/2) * (1/2) = (1/4) )
如果我们取x次,出现在答案的可能性就变成1−(34)x1-(\frac{3}{4})^x1(43)x
只要x够大,可能性就无限趋近于1
因此这个题可以这样搞,我们每次随机一个位置x,分别选取(x,x+1)或者(x,x+1)作为king子序列中的一部分,然后求公比,求最长子序列的长度,一直更新最大长度即可

代码:

#include <bits/stdc++.h> #include <unordered_map> #define debug(a, b) printf("%s = %d\n", a, b); using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int, int> PII; clock_t startTime, endTime; //Fe~Jozky const ll INF_ll= 1e18; const int INF_int= 0x3f3f3f3f; void read(){}; template <typename _Tp, typename... _Tps> void read(_Tp& x, _Tps&... Ar) {x= 0;char c= getchar();bool flag= 0;while (c < '0' || c > '9')flag|= (c == '-'), c= getchar();while (c >= '0' && c <= '9')x= (x << 3) + (x << 1) + (c ^ 48), c= getchar();if (flag)x= -x;read(Ar...); } template <typename T> inline void write(T x) {if (x < 0) {x= ~(x - 1);putchar('-');}if (x > 9)write(x / 10);putchar(x % 10 + '0'); } void rd_test() { #ifdef ONLINE_JUDGE #elsestartTime = clock ();freopen("data.in", "r", stdin); #endif } void Time_test() { #ifdef ONLINE_JUDGE #elseendTime= clock();printf("\nRun Time:%lfs\n", (double)(endTime - startTime) / CLOCKS_PER_SEC); #endif } mt19937 rnd(time(0)); int n; ll p; ll poww(ll a,ll b){ll ans=1;while(b){if(b&1)ans=ans*a%p;a=a*a%p;b>>=1;}return ans%p; } const int maxn=2e5+9; ll dp[maxn]; ll a[maxn];unordered_map<ll,ll>mp; ll solve(int l,int r){ll res=0;ll q,inv;//概率q=1ll*a[r]*poww(a[l],p-2)%p; // cout<<"q="<<q<<endl;inv=poww(q,p-2);for(int i=1;i<=n;i++){ll pre=1ll*a[i]*inv%p;if(mp.count(pre))dp[i]=mp[pre]+1;else dp[i]=1;mp[a[i]]=max(mp[a[i]],dp[i]);res=max(res,dp[i]);}mp.clear();return res; } int main() {//rd_test();int t;read(t);while(t--){scanf("%d%lld",&n,&p);for(int i=1;i<=n;i++)read(a[i]);ll ans=0;for(int i=1;i<=25;i++){int x=rnd()%(n-1)+1; // printf("%d %d\n",x,x+1);if(x+1<=n)ans=max(ans,solve(x,x+1));if(x+2<=n)ans=max(ans,solve(x,x+2)); }if(ans*2<n)printf("-1\n");else printf("%lld\n",ans);}//Time_test(); }

总结

以上是生活随笔为你收集整理的King Gym - 102471H的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。