2 倍时间暴力求卡常
查看原帖
2 倍时间暴力求卡常
1125291
ZMQ_Ink6556楼主2025/8/5 15:51

submission

代码:

#include<bits/stdc++.h>
using namespace std;
int n , c[1000005] , tmp , tmp2;
long long a , b , tmp3 , ans = 1000000000000000018ll;
unordered_map<long long , long long> mp , mp2;
inline long long ti(long long p , int q)
{
	return (p << 20ll) + q;
}
inline int fl(long long p)
{
	return (p >> 20);
}
inline int fr(long long p)
{
	return ((p >> 20) << 20) ^ p;
}
inline void in(long long x , long long y)
{
	if(mp2.find(x) != mp2.end())
	{
		mp2[x] = min(mp2[x] , y);
		return;
	}
	mp2[x] = y;
	return;
}
char buf[1 << 16] , *p1 = buf , *p2 = buf;
inline char get_char()
{
    return p1 == p2 && (p2 = (p1 = buf) + fread(buf , 1 , 1 << 16 , stdin) , p1 == p2) ? EOF : *p1++;
}
inline int read()
{
    int x = 0 , f = 1;
    char ch = get_char();
    while (ch < '0' || ch > '9')
	{
		if(ch == '-')
		{
			f = -1;
		}
		ch = get_char();
	}
    while (ch >= '0' && ch <= '9')
	{
        x = x * 10 + (ch ^ 48);
        ch = get_char();
    }
    return x * f;
}
signed main()
{
	ios::sync_with_stdio(0);
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	n = read();
	a = read();
	b = read();
	for(int i = 1 ; i <= n ; i++)
	{
		c[i] = read();
	}
	mp[ti(c[1] , 2)] = 0;
	mp[ti(c[1] - 1 , 2)] = b;
	mp[ti(c[1] + 1 , 2)] = b;
	unordered_map<long long , long long>::iterator j;
	for(int i = 2 ; i <= n ; i++)
	{
		mp2.clear();
		in(ti(c[i] , 0) , (i - 1) * a);
		in(ti(c[i] - 1 , 0) , (i - 1) * a + b);
		in(ti(c[i] + 1 , 0) , (i - 1) * a + b);
		for(j = mp.begin() ; j != mp.end() ; j++)
		{
			tmp = fl(j -> first);
			tmp2 = fr(j -> first);
			if(tmp2 == 1 || tmp2 == 2)
			{
				in(ti(tmp , 1) , j -> second + a);
			}
			tmp3 = __gcd(tmp , c[i]);
			if(tmp3 != 1)
			{
				if(tmp2 == 2)
				{
					in(ti(tmp3 , 2) , j -> second);
				}
				else
				{
					in(ti(tmp3 , 0) , j -> second);
				}
			}
			tmp3 = __gcd(tmp , c[i] - 1);
			if(tmp3 != 1)
			{
				if(tmp2 == 2)
				{
					in(ti(tmp3 , 2) , j -> second + b);
				}
				else
				{
					in(ti(tmp3 , 0) , j -> second + b);
				}
			}
			tmp3 = __gcd(tmp , c[i] + 1);
			if(tmp3 != 1)
			{
				if(tmp2 == 2)
				{
					in(ti(tmp3 , 2) , j -> second + b);
				}
				else
				{
					in(ti(tmp3 , 0) , j -> second + b);
				}
			}
		}
		swap(mp , mp2);
		if(mp.size() > 100) // 检查复杂度
		{
			exit(2);// 未出现
		}
		if(i > 600000) // 查找 TLE 时间
		{
			exit(1); // 2999ms
		}
	}
	for(j = mp.begin() ; j != mp.end() ; j++)
	{
		ans = min(ans , j -> second);
	}
	cout << ans;
	return 0;
}

求卡常

2025/8/5 15:51
加载中...