比赛链接:
https://ac.nowcoder.com/acm/contest/883#question
D. Big Integer
题意:
给出$p,n,m$
其中p为素数,求出多少个$pair(i,j),1\leq i \leq n,1\leq j \leq m$,满足下面式子
$\frac{10^{i^{j}}-1}{9}\equiv 0(mod\ p)$
分析:
ac代码:
#include<bits/stdc++.h> #define ll long long #define ull unsigned long long #define pa1 pair<int,int> #define pa2 pair<ll,int> using namespace std; const int maxn=1000+10; ll phi(ll x) { ll res=x; for(ll i=2;i*i<=x;i++){ //cout<<x<<" "<<i<<endl; if(x%i==0){ res=res/i*(i-1); while(x%i==0)x/=i; } } if(x>1)res=res/x*(x-1); return res; } ll qpow(ll x,ll y,ll mod) { __int128 res=1,k=x;//因为待会mod可能为9e9 while(y){ if(y%2)res=res*k%mod; k=k*k%mod; y/=2; } return res; } vector<pa2>ve2; ll qpow1(ll x,ll y) { ll res=1; for(int i=1;i<=y;i++)res=res*x; return res; } int main() { //cout<<qpow(2,3,3)<<endl; int T; scanf("%d",&T); while(T--){ ll n,m,p; scanf("%lld %lld %lld",&p,&n,&m); if(p==2||p==5){ printf("0\n"); continue; } ll zz=phi(9*p),x; x=zz; for(ll i=1;i*i<=zz;i++) if(zz%i==0){ if(qpow(10,i,p*9)==1)x=min(x,i); if(qpow(10,zz/i,p*9)==1)x=min(x,zz/i); } ll g=x; //以下代码寻找pair(i,j)i^j%x==0 for(ll i=2;i*i<=g;i++){ if(g%i==0){ pa2 now=make_pair(i,0); while(g%i==0)g/=i,now.second++; ve2.push_back(now); } } if(g!=1)ve2.push_back(make_pair(g,1)); ll ans=0; for(int j=1;j<=min(m,(ll)30);j++){ ll g=1; for(int i=0;i<ve2.size();i++) g=g*qpow1(ve2[i].first,(ve2[i].second+j-1)/j); ll res=n/g; ans+=res; if(j==30)ans+=(m-j)*res; } printf("%lld\n",ans); ve2.clear(); } return 0; }
F. Planting Trees
题意:
找到最大的矩形,矩形里面最大元素减最小元素不大于$m$
分析:
ac代码:
#include <bits/stdc++.h> #define ll long long #define pa pair<int,int> using namespace std; const long long INF64 = 1e18; const int maxn=500+10; const int maxm=405; struct Sk{ pa num[maxn]; int st,en; void show(){ for(int i=st;i<=en;i++){ printf("%d ",num[i].first); } printf("\n"); } }sk1,sk2; int ma[maxn][maxn]; pa lis[maxn]; int main() { int T; scanf("%lld",&T); while(T--){ int n,m,ans=0; scanf("%d %d",&n,&m); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) scanf("%d",&ma[i][j]); for(int up=1;up<=n;up++){ for(int i=1;i<=n;i++)lis[i].first=lis[i].second=ma[up][i]; for(int down=up;down<=n;down++){ int res=0; for(int i=1;i<=n;i++) lis[i].first=max(lis[i].first,ma[down][i]), lis[i].second=min(lis[i].second,ma[down][i]); int l=1; sk1.st=sk2.st=sk1.en=sk2.en=1; sk1.num[1]=make_pair(lis[1].first,1); sk2.num[1]=make_pair(lis[1].second,1); for(int r=1;r<=n;r++){ //cout<<" lisr"<<lis[r].first<<endl; while(l<r&&sk1.num[sk1.st].first-sk2.num[sk2.st].first>m){ l++; while(sk1.num[sk1.st].second<l)sk1.st++; while(sk2.num[sk2.st].second<l)sk2.st++; } // cout<<"-------"<<endl; // sk1.show(); // sk2.show(); // cout<<"-------"<<endl; // cout<<"zzz"<<l<<" "<<r<<endl; if(sk1.num[sk1.st].first-sk2.num[sk2.st].first<=m) res=max(res,r-l+1); while(sk1.en>=sk1.st&&sk1.num[sk1.en].first<lis[r+1].first)sk1.en--; sk1.num[++sk1.en]=make_pair(lis[r+1].first,r+1); while(sk2.en>=sk2.st&&sk2.num[sk2.en].first>lis[r+1].second)sk2.en--; sk2.num[++sk2.en]=make_pair(lis[r+1].second,r+1); } ans=max(ans,res*(down-up+1)); } } printf("%d\n",ans); } return 0; }