BZOJ1485: [HNOI2009] Interesting sequence

Solution: Consider adding numbers in order from small to large, adding odd-numbered positions as a push, and adding even-numbered positions as a stack. Why? Consider that we want to ensure that the adjacent odd number is less than the even number, so we must first fill in an odd number position before filling in the even number position, that is, always ensure that the odd number >= even number, and finally the odd number is equal to the even number. Observing this property, we should think of the Cattelan number and apply the formula to solve it. The modulus of this question may be a composite number, and there may not be an inverse element! ! So, break down the calculations and combine them at the end. By the way, I tried constant optimization. . . However, my code is too ugly, I'm afraid I can't save it.

#include <bits/stdc++.h>
typedef unsigned long long ull;
using namespace std;
int notp[2000007],num[2000007],nxt[2000007],n,P,p[2000007],tn;
void init() {
    notp[1]=1;nxt[1]=1; tn = (n<<1);
    for(register int i=1;i<=tn;++i) {
        if(!notp[i])p[++p[0]]=i,nxt[i]=i;
        for(register int j=1;j<=p[0]&&p[j]*i<=tn;++j) {
            notp[i*p[j]]=1;nxt[i*p[j]]=p[j];
            if(i%p[j]==0)break;
        }
    }
}
inline void add(ull a,ull v) {
    while(a != 1) {
        num [nxt [a]]+= v;
        a/=nxt[a];
    }
}
inline ull q_pow(ull a,int b) {
    ull years=1;
    while(b) {
        if(b&1)ans=(ans*a)%P;
        a=(a*a)%P;
        b>>=1;
    }
    return (int)ans;
}
inline ull merge() {
    ull years = 1;
    register int i;
    for( i=1; i<=p[0]; i+=3) {
        ans = (ans%P*q_pow(p[i],num[p[i]])%P)%P;
        ans = (ans%P*q_pow(p[i+1],num[p[i+1]])%P)%P;
        ans = (ans%P*q_pow(p[i+2],num[p[i+2]])%P)%P;
    }
    for(;i<=p[0];++i) ans = (ans%P*q_pow(p[i],num[p[i]])%P)%P;
    return ans%P;
}
inline void write(ull x) {
    if(x>=10)write(x/10);
    putchar(x%10+'0');
}
// (while) better than (for)
// (!=) better than (>)
// (int) better than (ull) better than (ll)
int main() {
    scanf("%d%d",&n,&P);
    init();
    for(ull i=1;i<=tn;++i) add(i,1);
    for(ull i=1;i<=n;++i) add(i,-2);
    add(n+1,-1);
    write(merge());
}

  

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324809552&siteId=291194637