2020牛客暑期多校训练营(第九场)A I F E K 补题

I题签到:给你n个数,用n位数字去组成2个整数(不含前导0),输出两个数乘积的最小值。

思维题,选择最小不为0的数给 整数a,其他的数字按从小到大给 整数b(注意前导0),输出乘积即可。使用桶排对0到9进行计数。
注意,数据范围过大,需要使用大数。

#include <iostream>
#include <algorithm>
#include <stack>
using namespace std;
const int maxn = 1e5 + 50;
int vis[15];

string multiply(string num1, string num2) {
        int l1 = num1.length();
        int l2 = num2.length();
        if (num1 == "0" || num2 == "0")
            return "0";
        string res(l1 + l2, '0');
        for (int i = l1 - 1; i >= 0; i--)
        {
            int step = 0;
            for (int j = l2 - 1; j >= 0; j--)
            {
                int mul = (num1[i] - '0') * (num2[j] - '0');
                int sum = res[i+j+1] - '0' + step + mul % 10;
                res[i+j+1] = sum % 10 + '0';
                step = sum / 10 + mul / 10;
            }
            res[i] += step;
        }
        for (int i = 0; i < l1 + l2; i++)
        {
            if (res[i] != '0')
                return res.substr(i);
        }
        return "0";
}

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int t;
	cin >> t;
	while(t--)
	{
		int n;
		cin >> n;
		for(int i = 0; i <= 9; i++) vis[i] = 0;
		for(int i = 1; i <= n; i++)
		{
			int a;
			cin >> a;
			vis[a]++;
		}
		string a = "",b = "";
		for(int i = 1; i <= 9; i++)
		{
            if(vis[i] && b.size() == 0)
			{
				b += '0' + i;
				vis[i]--;
			}
			if(vis[i] && a.size() == 0)
			{
				a += '0' + i;
				vis[i]--;
			}
			if(a.size() != 0 && b.size() != 0)
			{
				break;
			}
		}
		for(int i = 0; i <= 9;)
		{
			if(vis[i])
			{
				a += '0' + i;
				vis[i]--;
			}
			if(!vis[i]) i++;
		}
	//	cout << a << " " << b << endl;
		cout << multiply(a,b) << endl;
	}
	return 0;
}

A:给你一个字符串,按照要求计算字符串的值。

使用栈进行中值表达式的计算的变形。

#include <bits/stdc++.h>
using namespace std;
struct bint:vector<int>
{
    void format();
    bint(int n)
    {
        do push_back(n % 10), n /= 10; while (n);
    }
    bint(long long n)
    {
        do push_back(n % 10), n /= 10; while (n);
    }
    bint(string s)
    {
        for (int i = s.size() - 1; i >= 0; i --) push_back(s[i] - '0');
    }
    bint()
    {

    }
};
istream& operator>>(istream& in, bint& n);
ostream& operator<<(ostream& out, bint n);
bool operator<(bint a, bint b);
bool operator<=(bint a, bint b);
bool operator>(bint a, bint b);
bool operator>=(bint a, bint b);
bool operator==(bint a, bint b);
bool operator!=(bint a, bint b);
bint operator+(bint a, bint b);
bint operator-(bint a, bint b);
bint operator*(bint a, bint b);
bint operator/(bint a, bint b);
bint operator%(bint a, bint b);
template<typename T>
bint operator*(bint a, T b);
template<typename T>
bint operator/(bint a, T b);
template<typename T>
bint operator%(bint a, T b);
template<typename T>
bint operator*(T a, bint b);
bint divmode(bint& a, bint b);
template<typename T>
bint divmode(bint a, T b, T& r);
template<typename T>
void operator+=(T& a, T b);
template<typename T>
void operator-=(T& a, T b);
template<typename T>
void operator*=(T& a, T b);
template<typename T>
void operator/=(T& a, T b);
template<typename T>
void operator%=(T& a, T b);
void operator--(bint& a);
void operator++(bint& a);
void bint::format()
{
    while(size() > 1 && back() == 0) pop_back();
}
istream& operator>>(istream& in, bint& n)
{
    string s;
    in >> s;
    n.clear();
    for (int i = s.size() - 1; i >= 0; i --) n.push_back(s[i] - '0');
    return in;
}
ostream& operator<<(ostream& out, bint n)
{
    for (int i = n.size() - 1; i >= 0; i --) out << n[i];
    return out;
}
bool operator<(bint a, bint b)
{
    if (a.size() != b.size()) return a.size() < b.size();
    for (int i = a.size() - 1; i >= 0; i --)
        if (a[i] != b[i])
            return a[i] < b[i];
    return false;
}
bool operator<=(bint a, bint b)
{
    return a < b || a == b;
}
bool operator>(bint a, bint b)
{
    return !(a <= b);
}
bool operator>=(bint a, bint b)
{
    return !(a < b);
}
bool operator==(bint a, bint b)
{
    if (a.size() != b.size()) return false;
    for (int i = a.size() - 1; i >= 0; i --)
        if (a[i] != b[i])
            return false;
    return true;
}
bool operator!=(bint a, bint b)
{
    return !(a == b);
}
bint operator+(bint a, bint b)
{
    int t = 0;
    bint c;
    for (int i = 0; i < a.size() || i < b.size(); i ++)
    {
        if (i < a.size()) t += a[i];
        if (i < b.size()) t += b[i];
        c.push_back(t % 10);
        t /= 10;
    }
    if (t) c.push_back(t);
    return c;
}
bint operator-(bint a, bint b)
{
    if (b > a)
    {
        cerr << "Error occurs at BigInteger operator-(BigInteger, BigInteger)" << endl;
        cerr << "A negative result is produced" << endl;
        return a;
    }
    int t = 0;
    bint c;
    for (int i = 0; i < a.size() ; i ++)
    {
        t += a[i];
        if (i < b.size()) t -= b[i];
        if (t < 0) c.push_back(t + 10), t = -1;
        else c.push_back(t), t = 0;
    }
    c.format();
    return c;
}
bint operator*(bint a, bint b)
{
    bint c;
    c.assign(a.size() + b.size() - 1, 0);
    for(int i = 0; i < a.size(); i ++)
        for(int j = 0; j < b.size(); j ++)
            c[i + j] += a[i] * b[j];
    for (int i = 0; i < c.size() - 1; i ++)
        if (c[i] >= 10)
            c[i + 1] += c[i] / 10, c[i] %= 10;
    if (c[c.size() - 1] >= 10) c.push_back(c[c.size() - 1] / 10), c[c.size() - 2] %= 10;
    c.format();
    return c;
}
bint operator/(bint a, bint b)
{
    return divmode(a, b);
}
bint operator%(bint a, bint b)
{
    divmode(a, b);
    return a;
}
template<typename T>
bint operator*(bint a, T b)
{
    bint c;
    T t = 0;
    for (int i = 0; i < a.size() || t; i ++)
    {
        if (i < a.size()) t += a[i] * b;
        c.push_back(t % 10);
        t /= 10;
    }
    c.format();
    return c;
}
template<typename T>
bint operator*(T a, bint b)
{
    return b * a;
}
template<typename T>
bint operator/(bint a, T b)
{
    T r = 0;
    return divmode(a, b, r);
}
template<typename T>
T operator%(bint a, T b)
{
    T r;
    divmode(a, b, r);
    return r;
}
bint divmode(bint& a, bint b)
{
    if (b == 0)
    {
        cerr << "Error occurs at BigInteger operator/(BigInteger, BigInteger)" << endl;
        cerr << "Divided by zero" << endl;
        return a;
    }
    bint c, d, e;
    for (int i = a.size() - b.size(); a >= b; i --)
    {
        d.clear(), d.assign(i + 1, 0), d.back() = 1;
        int l = 0, r = 9, m;
        while (l < r)
        {
            m = l + r + 1 >> 1;
            e = b * d * m;
            if (e <= a) l = m;
            else r = m - 1;
        }
        a -= b * d * l, c += d * l;
    }
    return c;
}
template<typename T>
bint divmode(bint a, T b, T& r)
{
    bint c;
    r = 0;
    for (int i = a.size() - 1; i >= 0; i -- )
    {
        r = r * 10 + a[i];
        c.push_back(r / b);
        r %= b;
    }
    reverse(c.begin(), c.end());
    c.format();
    return c;
}
template<typename T>
void operator+=(T& a, T b)
{
    a = a + b;
}
template<typename T>
void operator-=(T& a, T b)
{
    a = a - b;
}
template<typename T>
void operator*=(T& a, T b)
{
    a = a * b;
}
template<typename T>
void operator/=(T& a, T b)
{
    a = a / b;
}
template<typename T>
void operator%=(T& a, T b)
{
    a = a % b;
}
void operator--(bint& a)
{
    a -= bint(1);
}
void operator++(bint& a)
{
    a += bint(1);
}
string s;
int main()
{
    cin >> s;
    stack<bint> num;
    stack<char> p;
	//建立数字和字符的栈
    bint cnt;
    for(int i = 0; i < s.length();)
    {
    	cnt = 0;
    	//记录数字,数字可能不止1位
    	//按照题目意思,是完全分解,所以数字只会出现0和2.但是没有准确说明,所以我用cnt记录数字
    	if(s[i] >= '0' && s[i] <= '9')
    	{
    		while(s[i] >= '0' && s[i] <= '9')
    		{
    			cnt = cnt * 10 + s[i] - '0';
    			i++;
			}
			num.push(cnt);
			//将数字压入数字的栈中。
		}
		else if(s[i] == '+' || s[i] == '(')
		{
			p.push(s[i]);
			i++;
		}//将字符压入字符的栈中
		else if(s[i] == ')')
		{//读到右括号的时候需要进行结算,方便进行之后的计算。
			while(p.top() != '(')
			{//不断弹出,直到碰到左括号计算结束
				if(p.top() == '+')
				{
					//找到加号,那么拿出倒数两个数字相加,弹出,再将结果压入数字的栈中
					bint a = num.top();
					num.pop();
					bint b = num.top();
					num.pop();
					a += b;
					p.pop();
					num.push(a);
				}
			}
			p.pop();
			//记得把左括号也弹出
		//左括号前面肯定要计算次方
			bint a = num.top();
			num.pop();
			bint b = num.top();
			num.pop();
			bint c(1);
			//需要计算 b的a次方
			for(int i = 0; i < a; i++)
			{
				c *= b;
			}
			num.push(c);
			i++;
		}
	}
	bint ans(0);
	//最终,数字栈中都是被加号分割,没有括号的值
	//求和即可
	while(num.size())
	{
		ans += num.top();
		num.pop();
	}
	cout << ans << endl;
    return 0;
}

acwing闫雪灿的大数板子真好用。
其次,值得一提的是,python有可以直接调用的函数…
一行代码就可以ac,嘤嘤嘤
表达式中需要用**来表示乘方

print(eval(input().replace('(','**(')))

本题也可以使用递归的方法求解
递归的代码:


#include <bits/stdc++.h>
using namespace std;
struct bint:vector<int>
{
    void format();
    bint(int n)
    {
        do push_back(n % 10), n /= 10; while (n);
    }
    bint(long long n)
    {
        do push_back(n % 10), n /= 10; while (n);
    }
    bint(string s)
    {
        for (int i = s.size() - 1; i >= 0; i --) push_back(s[i] - '0');
    }
    bint()
    {

    }
};
istream& operator>>(istream& in, bint& n);
ostream& operator<<(ostream& out, bint n);
bool operator<(bint a, bint b);
bool operator<=(bint a, bint b);
bool operator>(bint a, bint b);
bool operator>=(bint a, bint b);
bool operator==(bint a, bint b);
bool operator!=(bint a, bint b);
bint operator+(bint a, bint b);
bint operator-(bint a, bint b);
bint operator*(bint a, bint b);
bint operator/(bint a, bint b);
bint operator%(bint a, bint b);
template<typename T>
bint operator*(bint a, T b);
template<typename T>
bint operator/(bint a, T b);
template<typename T>
bint operator%(bint a, T b);
template<typename T>
bint operator*(T a, bint b);
bint divmode(bint& a, bint b);
template<typename T>
bint divmode(bint a, T b, T& r);
template<typename T>
void operator+=(T& a, T b);
template<typename T>
void operator-=(T& a, T b);
template<typename T>
void operator*=(T& a, T b);
template<typename T>
void operator/=(T& a, T b);
template<typename T>
void operator%=(T& a, T b);
void operator--(bint& a);
void operator++(bint& a);
void bint::format()
{
    while(size() > 1 && back() == 0) pop_back();
}
istream& operator>>(istream& in, bint& n)
{
    string s;
    in >> s;
    n.clear();
    for (int i = s.size() - 1; i >= 0; i --) n.push_back(s[i] - '0');
    return in;
}
ostream& operator<<(ostream& out, bint n)
{
    for (int i = n.size() - 1; i >= 0; i --) out << n[i];
    return out;
}
bool operator<(bint a, bint b)
{
    if (a.size() != b.size()) return a.size() < b.size();
    for (int i = a.size() - 1; i >= 0; i --)
        if (a[i] != b[i])
            return a[i] < b[i];
    return false;
}
bool operator<=(bint a, bint b)
{
    return a < b || a == b;
}
bool operator>(bint a, bint b)
{
    return !(a <= b);
}
bool operator>=(bint a, bint b)
{
    return !(a < b);
}
bool operator==(bint a, bint b)
{
    if (a.size() != b.size()) return false;
    for (int i = a.size() - 1; i >= 0; i --)
        if (a[i] != b[i])
            return false;
    return true;
}
bool operator!=(bint a, bint b)
{
    return !(a == b);
}
bint operator+(bint a, bint b)
{
    int t = 0;
    bint c;
    for (int i = 0; i < a.size() || i < b.size(); i ++)
    {
        if (i < a.size()) t += a[i];
        if (i < b.size()) t += b[i];
        c.push_back(t % 10);
        t /= 10;
    }
    if (t) c.push_back(t);
    return c;
}
bint operator-(bint a, bint b)
{
    if (b > a)
    {
        cerr << "Error occurs at BigInteger operator-(BigInteger, BigInteger)" << endl;
        cerr << "A negative result is produced" << endl;
        return a;
    }
    int t = 0;
    bint c;
    for (int i = 0; i < a.size() ; i ++)
    {
        t += a[i];
        if (i < b.size()) t -= b[i];
        if (t < 0) c.push_back(t + 10), t = -1;
        else c.push_back(t), t = 0;
    }
    c.format();
    return c;
}
bint operator*(bint a, bint b)
{
    bint c;
    c.assign(a.size() + b.size() - 1, 0);
    for(int i = 0; i < a.size(); i ++)
        for(int j = 0; j < b.size(); j ++)
            c[i + j] += a[i] * b[j];
    for (int i = 0; i < c.size() - 1; i ++)
        if (c[i] >= 10)
            c[i + 1] += c[i] / 10, c[i] %= 10;
    if (c[c.size() - 1] >= 10) c.push_back(c[c.size() - 1] / 10), c[c.size() - 2] %= 10;
    c.format();
    return c;
}
bint operator/(bint a, bint b)
{
    return divmode(a, b);
}
bint operator%(bint a, bint b)
{
    divmode(a, b);
    return a;
}
template<typename T>
bint operator*(bint a, T b)
{
    bint c;
    T t = 0;
    for (int i = 0; i < a.size() || t; i ++)
    {
        if (i < a.size()) t += a[i] * b;
        c.push_back(t % 10);
        t /= 10;
    }
    c.format();
    return c;
}
template<typename T>
bint operator*(T a, bint b)
{
    return b * a;
}
template<typename T>
bint operator/(bint a, T b)
{
    T r = 0;
    return divmode(a, b, r);
}
template<typename T>
T operator%(bint a, T b)
{
    T r;
    divmode(a, b, r);
    return r;
}
bint divmode(bint& a, bint b)
{
    if (b == 0)
    {
        cerr << "Error occurs at BigInteger operator/(BigInteger, BigInteger)" << endl;
        cerr << "Divided by zero" << endl;
        return a;
    }
    bint c, d, e;
    for (int i = a.size() - b.size(); a >= b; i --)
    {
        d.clear(), d.assign(i + 1, 0), d.back() = 1;
        int l = 0, r = 9, m;
        while (l < r)
        {
            m = l + r + 1 >> 1;
            e = b * d * m;
            if (e <= a) l = m;
            else r = m - 1;
        }
        a -= b * d * l, c += d * l;
    }
    return c;
}
template<typename T>
bint divmode(bint a, T b, T& r)
{
    bint c;
    r = 0;
    for (int i = a.size() - 1; i >= 0; i -- )
    {
        r = r * 10 + a[i];
        c.push_back(r / b);
        r %= b;
    }
    reverse(c.begin(), c.end());
    c.format();
    return c;
}
template<typename T>
void operator+=(T& a, T b)
{
    a = a + b;
}
template<typename T>
void operator-=(T& a, T b)
{
    a = a - b;
}
template<typename T>
void operator*=(T& a, T b)
{
    a = a * b;
}
template<typename T>
void operator/=(T& a, T b)
{
    a = a / b;
}
template<typename T>
void operator%=(T& a, T b)
{
    a = a % b;
}
void operator--(bint& a)
{
    a -= bint(1);
}
void operator++(bint& a)
{
    a += bint(1);
}
const  int maxn = 2e4 + 50;
string s;
bint dfs(int &i){
    bint res = 0;
    i ++;
    while(s[i] != ')'){
        if(s[i] == '2'){
            if(s[i+1] == '(') 
			{
				bint num = 1;
				bint k = dfs(++i);
				for(bint j = 1; j <= k; j=j+1)
				{
					num *= (bint)2;
				}
				res += num; // 这里计算2的幂次方
			}
            else if(s[i+1] == '+') res += (bint)2, i ++;  // 
            else if(s[i+1] == ')') {res += (bint)2, i ++; break;}
        }
        if(s[i] == '0') {i ++; break;}
        if(s[i] == '+') i ++;
    }
    i ++;
    return res;
}
bint t[maxn];
int z = 0;
int main()
{

    cin >> s;
    for(int i = 0; i < s.length(); i++)
    {
    //	cout << i << endl;
    	if(s[i] == '2')
    	{//要进行2的乘方计算
			if(i+1 < s.length() && s[i+1] == '(')
			{
				bint sum = 1;
				bint k = dfs(++i);
				for(bint j = 1; j <= k; j = j + 1)
				{
					sum *= (bint)2;
				}
			//	cout << sum << endl;
				t[++z] = sum;	
			}
    		else
    		{
    			t[++z] = (bint)2;
			}
		}
	}
	//上述操作将所有内部的括号都加以计算,只保留了外部的括号
	//外部的括号由加号连接
	bint ans = 0;
	for(int i = 1; i <= z; i++)
	{
		ans += t[i];
	}
	cout << ans << endl;
    return 0;
}

F:从n天当中选择m天,每一天给出可能的选择,每天只能选择一个数字,问m天中选择的最大数字与最小数字的差,最小为多少。

数据比较水,直接按最小排序也能过…,但是肯定不推荐

由于数据量比较大,不能开二维数组。
所以,定义结构体数组,把每件衣服的对应天id,和价值w赋值。
因为我们要求最大值与最小值的最小差,所以,对数组,按照w进行排序。

那么可以把问题转化成:找到一个连续区间,使得区间内有来自m天的衣服,并且区间首尾w的差最小。
尺取法,代码内有尺取法的注释

#include <iostream>
#include <algorithm>
#include <unordered_map>
using namespace std;
const int maxn = 2e6 + 50;
const int inf = 0x3f3f3f3f;
struct node
{
	int id;
	int w;
}a[maxn];
int num = 0;
//开二维数组开不下,所以记录id,都存在一个数组里面
int n,m; 
bool cmp(node a, node b)
{
	if(a.w != b.w)
	return a.w < b.w;
	else return a.id < b.id;
}
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> n >> m;
	for(int i = 1; i <= n; i++)
	{
		int k;
		cin >> k;
		for(int j = 1; j <= k; j++)
		{
			int x;
			cin >> x;
			a[++num].w = x;
			a[num].id = i;
		}
	}
	sort(a+1,a+1+num,cmp);
	//先从大到小进行排序,之后再选择区间
	int l = 1;
	int ans = inf; 
	int cnt = 0;
	unordered_map<int,int> mp;
	for(int i = 1; i <= num; i++)
	{
		if(mp[a[i].id] == 0)//当前区间没有这天的衣服 
		{
			mp[a[i].id]++;
			cnt++;//区间里总衣服的数目增加 
		}
		else mp[a[i].id]++;
		
		while(cnt >= m)
		{
			if(mp[a[l].id] > 1)
			{
				mp[a[l].id]--;
				l++;
				//如果左边界出现多次,前推 
			}
			else
			{
				if(cnt - 1 >= m)
				{
					mp[a[l].id]--;
					l++;
					cnt--;
				}
				//如果区间内出现的种类多于m,也更新左边界
				else break; 
			}
		}
		if(cnt == m)
		{
			ans = min(ans,a[i].w - a[l].w);
		}
	}
	cout << ans << endl; 
	return 0;
} 

K:一棵n个节点的数,两个人a在节点1,b在节点n。a的移动速度为1,b的移动速度为2.给你一个时间T,前T秒a去找b,b不动。之后b去抓a,a逃跑。问在T秒时开始计算,最晚多少秒后,a会被b抓到。

队里OI佬写的lca + dfs。
我这里使用了3个dfs

dfs,用于找到a一开始向b走t秒之后的位置pos
dfsb,记录b走到所有点的时间。
dfsa,枚举a从pos开始走时,走到下一个点会不会被b抓到。一边枚举一边更新最大ans,如果被抓也更新ans,不被抓就继续搜

#include <iostream>
#include <algorithm>
#include <string.h>
using namespace std;
const int maxn = 1e5 + 5;
struct node
{
	long long v,next;
}e[2*maxn];
int cnt = 0;
int head[maxn];
void add(long long u,long long v)
{
	e[cnt].v = v;
	e[cnt].next = head[u];
	head[u] = cnt++;
}
int n,t;
int pos;
int dfs(int u, int fa, int step)
{//找到时间t后,A在哪个节点 
	if(u == n) return 1;//这条路可以到达n节点
	for(int i = head[u]; i != -1; i = e[i].next)
	{
		int v = e[i].v;
		if(v == fa) continue;
		//不能走回去
		int m = dfs(v,u,step+1);
		if(step == t && m == 1)
		{
			pos = u;
		}
		if(m == 1) return 1; 
	}
	return 0; 
}
int t1[maxn];
int ans = 0;
void dfsa(int u, int fa, int step)
{
	ans = max(ans,t1[u]);
	for(int i = head[u]; i != -1; i = e[i].next)
	{
		int v = e[i].v;
		if(v == fa) continue;
		if(step + 1 < t1[v])
		{
			dfsa(v,u,step+1);
			//如果走到v不会被抓到
			//尝试去走 
		}
		else ans = max(ans,t1[u]);
		//否则,就会被抓 
	}
}
void dfsb(int u,int fa,int step, int op)
{//因为速度为2,所以用op表示是走的第几步 
	t1[u] = step;
	for(int i = head[u]; i != -1; i = e[i].next)
	{
		int v = e[i].v;
		if(v == fa) continue;
		if(op)
		{
			dfsb(v,u,step+1,0);
			//0表示是2里面的第一步 
		}
		else dfsb(v,u,step,1);
		//1表示是第二步,所以step不变 
	}
} 
int main()					
{
	
	cin >> n >> t;
	memset(head, -1, sizeof(head));
	for(int i = 1; i < n; i++)
	{
		int u,v;
		cin >> u >> v;
		add(u,v);
		add(v,u);
	}
	dfs(1,-1,0);
	dfsb(n,-1,0,1);
	dfsa(pos,-1,0);
	cout << ans << endl;
	return 0;
}

E:求解表达式

首先,求解两个数的gcd,可以通过分解质因数得到。
假设x ^ i 与y ^ j有质因数p,其中x ^ i内有aa * i个p相乘,y ^ j内有bbj 个p相乘。
gcd对于质因数p来说,选择min(aa
i,bbj);
之后对于j所在的区间c,d.可以知道 aa
i/bb是一个分界点,左侧全是aai,右侧全是bbj,加上j是一个区间,等差数列即可。

在计算质因数p,以及得到p的幂次num时,计算num的过程中,num可能会爆long long,又由于是幂次,我们不能使用mod。
所以引入了费马小定理:a^(mod-1) % mod = 1
可以知道幂次以mod-1为周期,会回到1.所以我们计算num的时候%(mod-1)即可。

#include <iostream>
#include <algorithm>
using namespace std;
const int mod = 998244353;
const int Mod = mod - 1;
long long quickPower(long long x, long long y)//快速幂加取模 
{ 
    long long result = 1; // 定义答案 
    while (y > 0) // 当指数大于 0 时进行幂运算
    {
        if (y & 1) // y 和 1 做与运算,相当于对 2 求模
        {
            result = (result * x) % mod;// 如果 y 为奇数,则结果只乘一个 x
        }
        x = x * x % mod;  // x 乘二次方,下次使用
        y = y >> 1; // y 右移一位,相当于除以 2
    }
    return result % mod; // 返回结果 
}
long long ans = 1;
long long a,b,c,d,x,y;
void hanshu(int p)
{
	long long aa = 0, bb = 0;
	while(x % p == 0)
	{
		aa++;
		x /= p;
	}
	while(y % p == 0)
	{
		bb++;
		y /= p;
	}
	if(aa == 0 || bb == 0) return ;
	long long num = 0;//记录质因数P有多少个
	for(long long i = a; i <= b; i++)
	{
		long long j = aa * i / bb;
		long long temp,now;
		if(j < c)
		{
			temp = (d-c+1)*i % Mod * aa % Mod;
		}//全是i*aa 
		else if(j >= d)
		{//等差数列 
			temp = (c+d)*(d-c+1)/2 % Mod * bb % Mod;
		}
		else
		{
			now = (c+j)* (j-c+1)/2 % Mod * bb % Mod;
			temp = (now + (d-j)*i % Mod * aa % Mod) % Mod;
		}
		num = (num + temp) % Mod;
	}
	ans = ans * quickPower(p,num) % mod;
	//费马小定理:a^(mod-1)  % mod = 1 
	//即:以mod-1为周期,又会回到1,所以我在内部计算num时取模Mod  = mod-1
}
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> a >> b >> c >> d >> x >> y;
	for(int k = 2; k * k <= x; k++)
	{
		if(x % k == 0) hanshu(k);
	}
	if(x > 1) hanshu(x);
	cout << ans % mod << endl;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值