成绩: 100+60+50=210(考得一般,差不多刚好达到基础分)
很简单,直接暴力枚举 1... m 1...m 1...m间的每一个数,计算其与 n n n的 g c d gcd gcd,并将结果相乘,即可得到答案。
这样的做法接近于 O ( n ) O(n) O(n)。因此只能得80分,并不能AC。
代码如下:
#include
#define YKH 1000000007
#define LL long long
using namespace std;
LL n,m,ans=1;
inline char tc()
{
static char ff[100000],*A=ff,*B=ff;
return A==B&&(B=(A=ff)+fread(ff,1,100000,stdin),A==B)?EOF:*A++;
}
inline void read(LL &x)
{
x=0;char ch;
while(!isdigit(ch=tc()));
while(x=(x<<3)+(x<<1)+ch-'0',isdigit(ch=tc()));
}
inline void write(LL x)
{
if(x>9) write(x/10);
putchar(x%10+'0');
}
inline LL gcd(LL x,LL y)//求最大公因数
{
return y?gcd(y,x%y):x;
}
int main()
{
freopen("math.in","r",stdin),freopen("math_.out","w",stdout);
register LL i;LL flag=2;
read(n),read(m);
for(i=1;i<=m;++i) (ans*=gcd(i,n))%=YKH;//暴力枚举
return write(ans),0;
}
满分做法其实也并不难。
我们可以枚举n的每一个质因子(这只需要 O ( n ) O(\sqrt n) O(n)的时间),然后计算出在 1... m 1...m 1...m的范围中有多少个数含有这个质因子(可以直接用 m m m除以该质因子),然后快速幂求出这些因子的乘积即可。
我的代码中主要是用除余法来筛质因子,虽然这里用的并不标准,可能依然会有一部分的合数,但是在这题中并不影响答案,还能打打提高效率。
代码如下:
#include
#define YKH 1000000007
#define LL long long
using namespace std;
LL n,m,ans=1;
inline char tc()
{
static char ff[100000],*A=ff,*B=ff;
return A==B&&(B=(A=ff)+fread(ff,1,100000,stdin),A==B)?EOF:*A++;
}
inline void read(LL &x)
{
x=0;char ch;
while(!isdigit(ch=tc()));
while(x=(x<<3)+(x<<1)+ch-'0',isdigit(ch=tc()));
}
inline void write(LL x)
{
if(x>9) write(x/10);
putchar(x%10+'0');
}
inline bool Is_Prime(LL x)//判断n是否已是质数,若是,则可直接计算出答案
{
if(x<=1) return false;
for(register LL i=2;i*i<=x;++i) if(!(x%i)) return false;
return true;
}
inline LL quick_pow(LL x,LL y)//快速幂,大大减少计算乘积的时间
{
LL res=1;
while(y)
{
if(y&1) (res*=x)%=YKH;
(x*=x)%=YKH,y>>=1;
}
return res;
}
inline void doing(LL val)
{
LL x=val;//用一个变量来记录一下当前正在操作的数
while(!(n%x)) (ans*=quick_pow(val,m/x))%=YKH,x*=val;//判断n中是否含有多个该因子,对于每一个该因子,用快速幂计算出其乘积
n/=x/val;//将这个质因子从n中除去
if(Is_Prime(n))//判断当前的n是否已是质数
{
write(ans*quick_pow(n,m/n)%YKH);//输出最终答案
exit(0);//退出整个程序
}
}
int main()
{
freopen("math.in","r",stdin),freopen("math.out","w",stdout);
register LL i;LL flag=2;//flag表示i每次增加的数,使i始终可以表示为6n±1的形式,且不遗漏
read(n),read(m),doing(2),doing(3);//单独处理2,3两个质数
if(Is_Prime(n)) return write(ans*quick_pow(n,m/n)%YKH),0;
for(i=5;i<=m&&n>1;i+=flag,flag=6-flag) doing(i);//枚举每一个质数(6n±1不一定是质数,但大于2和3的质数一定可以用这种形式来表示)
return write(ans),0;
}
直接 O ( n 2 ) O(n^2) O(n2)枚举序列中的每一个区间,并在枚举的同时不断更新该区间的最大值和异或值,从而求出每一段区间的答案,将其累加就是最终的答案。
代码如下:
#include
#define YKH 1000000007
#define LL long long
#define N 100000
using namespace std;
LL n,ans=0,a[N+5],s[N+5];
inline char tc()
{
static char ff[100000],*A=ff,*B=ff;
return A==B&&(B=(A=ff)+fread(ff,1,100000,stdin),A==B)?EOF:*A++;
}
inline void read(LL &x)
{
x=0;char ch;
while(!isdigit(ch=tc()));
while(x=(x<<3)+(x<<1)+ch-'0',isdigit(ch=tc()));
}
inline void write(LL x)
{
if(x>9) write(x/10);
putchar(x%10+'0');
}
int main()
{
freopen("magic.in","r",stdin),freopen("magic.out","w",stdout);
register LL i,j;
for(read(n),i=1;i<=n;read(a[i]),s[i]=s[i-1]^a[i],++i);//用s[]数组累计异或值
for(i=1;i<=n;++i)
{
LL MAX=0;//用一个变量来记录每个区间的最大值
for(j=i;j<=n;++j)
MAX=max(MAX,a[j]),(ans+=MAX*(s[j]^s[i-1]))%=YKH;//枚举区间,更新最大值,求出答案
}
return write(ans),0;
}
这题暂时还没有改满,等改满后再更新该部分的题解。
赤裸裸的暴力,代码如下:
#include
#define LL long long
#define N 500000
using namespace std;
LL n,A,B,C,ans=0,a[N+5],b[N+5],c[N+5];
inline char tc()
{
static char ff[100000],*A=ff,*B=ff;
return A==B&&(B=(A=ff)+fread(ff,1,100000,stdin),A==B)?EOF:*A++;
}
inline void read(LL &x)
{
x=0;char ch;
while(!isdigit(ch=tc()));
while(x=(x<<3)+(x<<1)+ch-'0',isdigit(ch=tc()));
}
inline void write(LL x)
{
if(x>9) write(x/10);
putchar(x%10+'0');
}
int main()
{
freopen("dxxa.in","r",stdin),freopen("dxxa.out","w",stdout);
register LL i,j,k;
for(read(n),read(A),read(B),read(C),i=1;i<=n;read(a[i]),read(b[i]),read(c[i++]));
for(i=1;i<=A;++i)//暴力枚举A的大小
{
for(j=1;j<=B;++j)//暴力枚举B的大小
{
LL ok=1,Min=1;
for(k=1;k<=n;++k)//枚举每一张卡牌,得出最小的C
{
LL flag=(i<=a[k]?0:1)+(j<=b[k]?0:1);//计算A和B中有几个不大于这张卡牌
if(!flag||(flag==1&&c[k]==C))//如果无论如何都不可能有两个值大于当前卡牌的对应值,说明当前A和B的组合不合法
{
ok=0;
break;
}
if(flag==1) Min=max(Min,c[k]+1);//否则更新C的最小值
}
if(ok) ans+=C-Min+1;//更新答案
}
}
return write(ans),0;
}
这题暂时还没有改满,等改满后再更新该部分的题解。