1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
| #include<bits/stdc++.h> #define fo(i,a,b) for(int i=a;i<=b;i++) #define fd(i,a,b) for(int i=a;i>=b;i--) using namespace std;
typedef long long LL;
const int maxn=1e7+5, sqrtn=446; const LL mo=998244353;
int l,r;
int p0,p[maxn],minp[maxn],divp[maxn],maxp[maxn]; bool bz[maxn],cnt[maxn]; void Prime(int n) { fo(i,2,n) { if (!bz[i]) p[++p0]=i, cnt[i]=1, minp[i]=maxp[i]=p0, divp[i]=1; fo(j,1,p0) { if ((LL)i*p[j]>n) break; int nxt=i*p[j]; bz[nxt]=1; minp[nxt]=j; maxp[nxt]=maxp[i]; if (i%p[j]==0) { cnt[nxt]=cnt[i]^1; divp[nxt]=divp[i]; break; } else { cnt[nxt]=1; divp[nxt]=i; } } } }
LL Pow(LL x,int y) { LL re=1; for(; y; y>>=1, x=x*x%mo) if (y&1) re=re*x%mo; return re; }
bitset<sqrtn+2> zero,base[sqrtn+2],x,f[6005]; int basenum,bignum,big[maxn]; void add() { fd(i,sqrtn,1) if (x[i]) { if (base[i][i]) x^=base[i]; else { base[i]=x; basenum++; break; } } }
int T,bigP[maxn]; bool apr[maxn]; int main() { Prime(10000000); scanf("%d",&T); while (T--) { scanf("%d %d",&l,&r); if (r-l+1>6000) { int num=0; fo(i,l,r) if (maxp[i]>sqrtn && !apr[maxp[i]]) num++, apr[maxp[i]]=1; printf("%lld\n",Pow(2,r-l+1-num-sqrtn)); fo(i,l,r) if (maxp[i]>sqrtn) apr[maxp[i]]=0; } else { basenum=bignum=0; fo(i,1,sqrtn) base[i]=zero; fo(i,l,r) { x=zero; for(int ii=i; ii>1; ii=divp[ii]) if (minp[ii]>sqrtn) bigP[i]=minp[ii]; else x[minp[ii]]=cnt[ii]; if (bigP[i] && !big[bigP[i]]) { big[bigP[i]]=++bignum; f[bignum]=x; } else { if (bigP[i]) x^=f[big[bigP[i]]]; add(); } if (basenum==sqrtn) break; } printf("%lld\n",Pow(2,r-l+1-basenum-bignum)); fo(i,l,r) big[bigP[i]]=0; } } }
|