• 2021杭电多校1 1007/HDU 6956 Pass!


    题目链接:https://acm.hdu.edu.cn/showproblem.php?pid=6956

    题目大意:n个人传球,球最开始在第1个人手里,接下来每秒拿球的人必须传给另一个人,记合法方案为最后求传给第1个人,第i秒的合法方案数为f(i),现在知道了方案数,求最小时间t使得f(t) = x (mod 998244353)

    题目思路:通过递推得出

    \[f\left ( i \right )=\left ( n-2 \right )*f\left ( i-1 \right )+\left ( n-1 \right )*f\left ( i-2 \right ) \]

    再通过特征方程求解数列的通项公式得出

    \[f\left ( i \right )=\frac{ (n-1) *(-1)^{i}+ (n-1)^i}{n}\equiv x \]

    感谢这篇博客提供的解法:https://www.cnblogs.com/ZX-GO/p/15039734.html

    AC代码:

    #include <unordered_map>
    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <string>
    #include <stack>
    #include <deque>
    #include <queue>
    #include <cmath>
    #include <map>
    #include <set>
    using namespace std;
    typedef pair<int, int> PII;
    typedef long long ll;
    typedef unsigned long long ull;
    const int INF = 0x3f3f3f3f;
    const int N = 1e5 + 10, M = 1e7 + 30;
    const int base = 1e9;
    const int P = 131;
    const int mod = 998244353;
    const double eps = 1e-8;
    const double PI = acos(-1.0);
    ll hs[N], head[N], nexts[N], id[N], top;
    void insert(ll x, ll y, ll mod) //mod传 N
    {
    	ll k = x % mod;
    	hs[top] = x;
    	id[top] = y;
    	nexts[top] = head[k];
    	head[k] = top++;
    }
    ll find(ll x, ll mod)
    {
    	ll k = x % mod;
    	for (int i = head[k]; i != -1; i = nexts[i])
    		if (hs[i] == x)
    			return id[i];
    	return -1;
    }
    ll gcd(ll a, ll b)
    {
    	return b == 0 ? a : gcd(b, a % b);
    }
    ll BSGS(ll a, ll b, ll p, ll a1) //质数传1
    {
    	memset(head, -1, sizeof(head));
    	top = 1;
    	a %= p, b %= p;
    	if (a1 == 1 && 1 % p == b % p)
    		return 0;
    	if (a == 0)
    	{
    		if (b == 0)
    			return 1;
    		else
    			return -1;
    	}
    	//unordered_map<ll, ll> hash; //map  unordered_map 都试试
    	ll k = sqrt(p) + 1;
    	ll ak = 1;
    	for (ll i = 0; i < k; ++i)
    	{
    		ll t = ak * b % p;
    		insert(t, i, N);
    		//hash[t] = i;
    		ak = ak * a % p;
    	}
    	for (ll i = 0; i <= k; ++i)
    	{
    		/* if (hash.count(a1) && i * k - hash[a1] >= 0)
    			return i * k - hash[a1]; */
    		ll j = find(a1, N);
    		if (j != -1 && i * k - j >= 0)
    			return i * k - j;
    		a1 = a1 * ak % p;
    	}
    	return -1;
    }
    ll exBSGS(ll a, ll b, ll p)
    {
    	a %= p, b %= p;
    	if (b == 1 || p == 1)
    		return 0;
    	ll cnt = 0, a1 = 1;
    	ll d = gcd(a, p);
    	while (d > 1)
    	{
    		if (b % d)
    			return -1;
    		p /= d;
    		b /= d;
    		a1 = (a1 * a / d) % p;
    		++cnt;
    		if (b == a1)
    			return cnt;
    		d = gcd(a, p);
    	}
    	ll res = BSGS(a, b, p, a1);
    	if (res == -1)
    		return -1;
    	else
    		return res + cnt;
    }
    int main()
    {
    	int T;
    	scanf("%d", &T);
    	while (T--)
    	{
    		ll n, x;
    		scanf("%lld%lld", &n, &x);
    		ll ans1 = exBSGS((n - 1), n * x + (n - 1), mod);
    		if (ans1 % 2 == 0 || ans1 == -1)
    			ans1 = INF;
    		ll ans2 = exBSGS((n - 1), n * x + (1 - n), mod);
    		if (ans2 % 2 == 1 || ans2 == -1)
    			ans2 = INF;
    		ll ans = min(ans1, ans2);
    		if (ans == INF)
    			printf("-1\n");
    		else
    			printf("%lld\n", ans);
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    BZOJ.2916.[POI1997]Monochromatic Triangles(三元环)
    Codeforces.724G.Xor-matic Number of the Graph(线性基)
    BZOJ.3498.[PA2009]Cakes(三元环 枚举)
    BZOJ.3545.[ONTAK2010]Peaks(线段树合并)
    BZOJ.4919.[Lydsy1706月赛]大根堆(线段树合并/启发式合并)
    BZOJ.2212.[POI2011]Tree Rotations(线段树合并)
    BZOJ.4552.[HEOI2016/TJOI2016]排序(线段树合并/二分 线段树)
    Codeforces.547C.Mike and Foam(容斥/莫比乌斯反演)
    BZOJ.4516.[SCOI2016]幸运数字(线性基 点分治)
    页面置换算法
  • 原文地址:https://www.cnblogs.com/xiaopangpangdehome/p/15042792.html
Copyright © 2020-2023  润新知