CodeChef Chef and Functions
脑洞题,我们发现要算的最多60位,后面一定是1.
随手打了这样的暴力,以为能A,结果T,查了下,pow,exp,log,用的是泰勒展开一直以为是表
那么预处理加二分
#pragma GCC optimzie("-O2") #include<bits/stdc++.h> #define sight(x) ('0'<=x&&x<='9') #define mo 1000000007 #define LL long long #define pb push_back #define AA assert #define MM 1000000000010000000LL //#define int LL inline void read(int &x){ static int b;static char c; for(b=1,c=getchar();!sight(c);c=getchar()) if (c=='-') b=-1; for(x=0;sight(c);c=getchar()) x=x*10+c-48; x*=b; } inline void read(LL &x){ static int b;static char c; for(b=1,c=getchar();!sight(c);c=getchar()) if (c=='-') b=-1; for(x=0;sight(c);c=getchar()) x=x*10+c-48; x*=b; } void write(int x){if (x<10) {putchar(48+x);return;} write(x/10),putchar(48+x%10);} inline void writeln(int x){if (x<0) putchar('-'),x*=-1;write(x);putchar(' ');} using namespace std; LL Mo(LL x){if (x>=mo) x%=mo; if (x<0) (x%=mo)+=mo; return x;} int a[15007],q,T,n; LL XX,ans,x,RT; vector<LL> pw[107],pww[107]; void precal(){ LL i,j;int p; for(i = 3;i<100;i++){ pw[i].pb(1);pww[i].pb(1); } for(i = 1;i<=1000000;i++){ for(j = i*i*i,p = 3;p<100;j*=i,p++){ pw[p].pb(j); pww[p].pb(i); if(j>=MM/i) break; } } } LL calc(int i,LL x){ if(i == 1) return x; if(i == 2) return (LL)sqrtl(x); assert(i<=70); if(pw[i].size() == 0) return 1; int lo = 0, hi = pw[i].size() - 1; int mid, ret = 0; while(lo<=hi){ mid = (lo + hi) >>1; LL a = pw[i][mid]; if(a>x) hi = mid - 1; else lo = mid + 1,ret = mid; } return pww[i][ret]; } signed main () { precal(); read(T); while (T--) { read(n); XX=0; read(q); for(int i=1;i<=n;i++) { read(a[i]);if (a[i]<0) a[i]+=mo;} for(int i=n;i>60;i--) XX=Mo(XX+a[i]); n=min(60,n); while (q--) { read(x); ans=0; for(int i=1;i<=n;i++) ans=Mo(ans+(calc(i,x)%mo)*(LL)a[i]%mo); ans=Mo(ans+XX); AA(0<=ans&&ans<mo); writeln(ans); } } return 0; }