E-Groundhog Chasing Death2020牛客暑期多校训练营(第九场)
链接:https://ac.nowcoder.com/acm/contest/5674/E
来源:牛客网
示例1
输入
1 2 1 2 8 4
输出
2048
示例2
输入
1 2 3 4 120 180
输出
235140177
备注:
0⩽a,b,c,d⩽3×106 ,0<x,y⩽109 ,a⩽b,c⩽d.
题意:
求
题解:
这道题的思路历程真的是非常的久非常的久了,首先需要知道一个前提gcd的求法。
比如30分解质因子是21*31*51,84的分解质因子是22*31*71.gcd(30,84)=21 * 31=6.
得出一个结论他们的gcd就是共有因子数的最小幂的乘积,想一下就能验证这个结论。
gcd(30,84)=2min(1,2) * 3min(1,1).
然后幂的乘积就是一个累加(例如(23)2 * (22)4=28+6=214),所以把上面这个公式转换成下面这个公式
当时推出这个公式= = 开心坏了,直接跑了暴力后来算了算6e6 * 6e6,TLE的死死的
那么就想呗= =,能不能省掉一个for循环,然后然后就意识到min(x * i,y * j),当x * i不变的时候!!是可以直接算出结果的,只要判断他那个中值在哪里就可以了.
- 当x * i >= y * j,min(x * i,y * j)=y * j
- 当x * i < y * j,min(x * i,y * j)=x * i
由于j会变化(等差的),就用求和公式直接求就好了。
中值的计算:sh=x*i/y,在sh左边的都是x * i,在他右边的都是y * j
就可以把他用O(1)的时间复杂度给写出来了。
然后还是会T ,TTT了不知道多少发,才意识到,哇!是失精度了,指数也有可能超longlong,然后开了一个 __int128,就过了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#include<vector>
#include<time.h>
#include<queue>
#include<cmath>
#include<map>
#include<set>
#include<unordered_map>
#include<unordered_set>
#include<time.h>
#define ll __int128
using namespace std;
const int INF=0x3f3f3f3f;
const double pi=acos(-1.0),eps=1e-8;
const ll mod=998244353;
map<ll,ll>v1,v2;
map<ll,ll>ans;
inline void print(__int128 x)
{
if(x<0)
{
x=-x;
putchar('-');
}
if(x>9)
print(x/10);
putchar(x%10+'0');
}
template <typename _Tp> inline void read(_Tp&x)
{
char ch;
bool flag=0;
x=0;
while(ch=getchar(),!isdigit(ch))
if(ch=='-')
flag=1;
while(isdigit(ch))
x=x*10+ch-'0',ch=getchar();
if(flag)
x=-x;
}
ll quickpow(ll a,ll b)
{
ll res=1;
while(b)
{
if(b&1)
res=res*a%mod;
a=a*a%mod;
b>>=1;
}
return res;
}
int main()
{
ll a,b,c,d,x,y;
read(a);
read(b);
read(c);
read(d);
read(x);
read(y);
ll tmp=x,cnt;
for(ll i=2; i*i<=x; i++)
{
if(tmp%i==0)
{
cnt=0;
while(tmp%i==0)
{
cnt++;
tmp/=i;
}
v1[i]=cnt;
}
}
if(tmp!=1)
v1[tmp]=1;
tmp=y;
for(ll i=2; i*i<=y; i++)
{
if(tmp%i==0)
{
cnt=0;
while(tmp%i==0)
{
cnt++;
tmp/=i;
}
v2[i]=cnt;
}
}
if(tmp!=1)
v2[tmp]=1;
for(auto it:v1)
{
if(v2.count(it.first))
{
for(ll i=a; i<=b; i++)
{
ll t1=it.second;
ll t2=v2[it.first];
ll sh=i*t1/t2;
if(sh<c)
{
ans[it.first]+=t1*i*(d-c+1);
}else if(sh>=c&&sh<=d)
{
ans[it.first]+=(sh-c+1)*(t2*c+t2*sh)/2;
ans[it.first]+=(d-sh)*t1*i;
}
else ans[it.first]+=(d-c+1)*(t2*c+t2*d)/2;
}
}
}
ll xxx=1;
for(auto it:ans)
{
xxx=xxx*quickpow(it.first%mod,it.second);
xxx%=mod;
//printf("%lld,",it.second);
}
print(xxx);
//printf("Time = %.2f\n",(double)clock()/CLOCKS_PER_SEC);
return 0;
}
/*
1 2 1 2 120 180
1 2 1 2 30 42
*/