A:首先将p和q约分。容易发现相当于要求存在k满足bk mod q=0,也即b包含q的所有质因子。当然不能直接分解质因数,考虑每次给q除掉gcd(b,q),若能将q除至1则说明合法。但这个辣鸡题卡常,每求一次gcd都除干净就可以了。
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; #define ll long long char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;} ll gcd(ll n,ll m){return m==0?n:gcd(m,n%m);} ll read() { ll x=0,f=1;char c=getchar(); while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();} while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } int n; ll p,q,b; signed main() { #ifndef ONLINE_JUDGE freopen("a.in","r",stdin); freopen("a.out","w",stdout); #endif n=read(); while (n--) { p=read(),q=read(),b=read(); q/=gcd(p,q); ll u=gcd(b,q); while (u>1&&q>1) { while (q%u==0) q/=u; u=gcd(b,q); } if (q==1) puts("Finite");else puts("Infinite"); } return 0; //NOTICE LONG LONG!!!!! }
B:先考虑求出每个区间的f值。可以发现若区间长度为x,对于区间内第i个元素,其对最后答案是否产生贡献仅与C(x,i)是否为奇数有关。直接计算仍然是O(n3)的,由于C(i,j)=C(i-1,j-1)+C(i-1,j),f值我们也可以类似地递推得到,即f[i][j]=f[i+1][j]^f[i][j-1],考虑其中每个元素被计算的次数容易证明。然后再预处理正方形最大值,同样递推一下即可。于是就O(1)回答询问了。
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; #define ll long long #define N 5010 char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;} ll gcd(ll n,ll m){return m==0?n:gcd(m,n%m);} ll read() { ll x=0,f=1;char c=getchar(); while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();} while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } int n,q,a[N],f[N][N],ans[N][N]; signed main() { #ifndef ONLINE_JUDGE freopen("b.in","r",stdin); freopen("b.out","w",stdout); #endif n=read(); for (int i=1;i<=n;i++) a[i]=read(); for (int i=1;i<=n;i++) ans[i][i]=f[i][i]=a[i]; for (int i=2;i<=n;i++) for (int j=1;j<=n-i+1;j++) f[j][j+i-1]=f[j][j+i-2]^f[j+1][j+i-1]; for (int i=2;i<=n;i++) for (int j=1;j<=n-i+1;j++) ans[j][j+i-1]=max(max(ans[j][j+i-2],ans[j+1][j+i-1]),f[j][j+i-1]); q=read(); for (int i=1;i<=q;i++) { int l=read(),r=read(); printf("%d\n",ans[l][r]); } return 0; //NOTICE LONG LONG!!!!! }