2024寒假自主提升日记
2.7
闲话
做题纪要
SP26368 PWRANDMOD - Power and Mod
-
龟速乘板子。
点击查看代码
#define ll __int128_t ll read() { ll x=0,f=1; char c=getchar(); while(c>'9'||c<'0') { if(c=='-') { f=-1; } c=getchar(); } while('0'<=c&&c<='9') { x=x*10+c-'0'; c=getchar(); } return x*f; } void write(ll x) { if(x<0) { putchar('-'); x=-x; } if(x>9) { write(x/10); } putchar((x%10)+'0'); } ll smul(ll a,ll b,ll p) { ll ans=0; while(b>0) { if(b&1) { ans=(ans+a)%p; } b>>=1; a=(a+a)%p; } return ans; } ll qpow(ll a,ll b,ll p) { ll ans=1; while(b>0) { if(b&1) { ans=smul(ans,a,p); } b>>=1; a=smul(a,a,p); } return ans; } int main() { ll t,a,b,p,i; t=read(); for(i=1;i<=t;i++) { a=read(); b=read(); p=read(); write(qpow(a,b,p)); cout<<endl; } return 0; }
SP277 CTGAME - City Game
2.8
闲话
做题纪要
2.9
闲话
做题纪要
luogu P2440 木材加工
-
简单的二分答案,为什么我考场上没有看出来醉了。
-
注意可能会出现除数为 \(0\) 的情况,即 \(mid=\left\lfloor\dfrac{0+1}{2}\right\rfloor=0\) 时。将二分左端点初始化为 \(1\) 或对 \(mid=0\) 进行特判即可。
点击查看代码
int a[1000001]; bool check(int mid,int n,int m) { int sum=0,i; for(i=1;i<=n;i++) { sum+=a[i]/mid; } return sum>=m; } int main() { int n,m,ans,l=1,r=0,mid,i; cin>>n>>m; for(i=1;i<=n;i++) { cin>>a[i]; r=max(r,a[i]); } while(l<=r) { mid=(l+r)/2; if(check(mid,n,m)==true) { ans=mid; l=mid+1; } else { r=mid-1; } } cout<<ans<<endl; return 0; }
CF1331G Lingua Romana
-
愚人节的题,建议去看官方题解要简化题意。
点击查看代码
double a[1001]; int main() { int i; for(i=1;i<=11;i++) { cin>>a[i]; } for(i=11;i>=1;i--) { if(a[i]<5) { printf("f(%.0lf) = %.2lf\n",a[i],5*a[i]*a[i]*a[i]+sqrt(abs(a[i]))); } else { printf("f(%.0lf) = MAGNA NIMIS!\n",a[i]); } } return 0; }
2.10
闲话
做题纪要
HZOJ 863. 金牌
- 详见 2024初三年前集训测试2 T4 金牌 。
luogu P8670 [蓝桥杯 2018 国 B] 矩阵求和
2.11
闲话
做题纪要
luogu P4783 【模板】矩阵求逆
-
矩阵求逆板子。
-
若对于矩阵 \(A\) 存在一个矩阵 \(A^{-1}\) 使得 \(A \times A^{-1}=I\) 且 \(A^{-1} \times A =I\) ,其中 \(I\) 为单位矩阵 \(I= \begin{bmatrix} 1 & 0 & \cdots & 0 \\ 0 & 1 & \cdots & 0 \\ \vdots & \vdots & \ddots & \vdots \\ 0 & 0 & \cdots & 1 \end{bmatrix}\) ,则称 \(A\) 是可逆的且逆是唯一的, \(A^{-1}\) 为 \(A\) 的逆矩阵。
-
已知 \(\begin{bmatrix} A & I \end{bmatrix}\) ,考虑将其变成 \(\begin{bmatrix} I & A^{-1} \end{bmatrix}\) 。第一种方法是 \(\begin{bmatrix} A & I \end{bmatrix} \times A^{-1}= \begin{bmatrix} I & A^{-1} \end{bmatrix}\) ;另一种方法是对 \(A\) 进行高斯消元,使其变成系数为 \(1\) 的对角矩阵,变成 \(\begin{bmatrix} I & A^{-1} \end{bmatrix}\) 。
点击查看代码
ll a[1001][1001]; ll qpow(ll a,ll b,ll p) { ll ans=1; while(b>0) { if(b&1) { ans=ans*a%p; } b>>=1; a=a*a%p; } return ans; } int main() { ll n,inv,val=0,flag=0,i,j,k,p=1000000007; cin>>n; for(i=1;i<=n;i++) { a[i][i+n]=1; for(j=1;j<=n;j++) { cin>>a[i][j]; } } for(i=1;i<=n;i++) { val=i; for(j=i+1;j<=n;j++) { if(abs(a[j][i])-abs(a[val][i])>0) { val=j; } } for(j=1;j<=2*n;j++) { swap(a[i][j],a[val][j]); } if(a[i][i]==0) { flag=1; cout<<"No Solution"<<endl; break; } else { inv=qpow(a[i][i],p-2,p); for(j=1;j<=n;j++) { if(j!=i) { for(k=i+1;k<=2*n;k++) { a[j][k]=(a[j][k]-a[i][k]*(a[j][i]*inv%p)%p+p)%p; } } } for(j=1;j<=2*n;j++) { a[i][j]=a[i][j]*inv%p; } } } if(flag==0) { for(i=1;i<=n;i++) { for(j=n+1;j<=2*n;j++) { cout<<a[i][j]<<" "; } cout<<endl; } } return 0; }
2.12
闲话
做题纪要
luogu P2044 [NOI2012] 随机数生成器
-
令 \(F_{n}=\begin{bmatrix} x_{n} & c \end{bmatrix}\) ,容易有 \(\begin{aligned} F_{n} &=\begin{bmatrix} x_{n} & c \end{bmatrix} \\ &=\begin{bmatrix} x_{n-1} & c \end{bmatrix} \times \begin{bmatrix} a & 0 \\ 1 & 1 \end{bmatrix} \\ &=\begin{bmatrix} x_{n-2} & c \end{bmatrix} \times \begin{bmatrix} a & 0 \\ 1 & 1 \end{bmatrix}^{2} \\ &=\begin{bmatrix} x_{n-3} & c \end{bmatrix} \times \begin{bmatrix} a & 0 \\ 1 & 1 \end{bmatrix}^{3} \\ &=\dots \\ &=\begin{bmatrix} x_{0} & c \end{bmatrix} \times \begin{bmatrix} a & 0 \\ 1 & 1 \end{bmatrix}^{n} \\ &=F_{0} \times \begin{bmatrix} a & 0 \\ 1 & 1 \end{bmatrix}^{n} \end{aligned}\) 。
点击查看代码
struct Matrix { ll ma[5][5]; Matrix() { memset(ma,0,sizeof(ma)); } }f,a; ll read() { ll x=0,f=1; char c=getchar(); while(c>'9'||c<'0') { if(c=='-') { f=-1; } c=getchar(); } while('0'<=c&&c<='9') { x=x*10+c-'0'; c=getchar(); } return x*f; } void write(ll x) { if(x<0) { putchar('-'); x=-x; } if(x>9) { write(x/10); } putchar((x%10)+'0'); } Matrix mul(Matrix a,Matrix b,ll n,ll m,ll k,ll p) { Matrix c; for(ll i=1;i<=n;i++) { for(ll j=1;j<=k;j++) { for(ll h=1;h<=m;h++) { c.ma[i][j]=(c.ma[i][j]+(a.ma[i][h]%p)*(b.ma[h][j]%p)%p)%p; } } } return c; } Matrix qpow(Matrix a,ll b,ll p,ll n) { Matrix ans; for(ll i=1;i<=n;i++) { ans.ma[i][i]=1; } while(b>0) { if(b&1) { ans=mul(ans,a,n,n,n,p); } b>>=1; a=mul(a,a,n,n,n,p); } return ans; } int main() { ll p,b,g,n=1,m=2,k=2; p=read(); a.ma[1][1]=read(); f.ma[1][2]=read(); f.ma[1][1]=read(); b=read(); g=read(); a.ma[1][2]=0; a.ma[2][1]=a.ma[2][2]=1; write(mul(f,qpow(a,b,p,m),n,m,k,p).ma[1][1]%g); return 0; }
BZOJ4128 Matrix
-
用
map
重载运算符即可。 -
因常数巨大,故尽可能减少 \(BSGS\) 中多次矩阵快速幂的使用。
点击查看代码
ll n; struct Matrix { ll ma[80][80]; Matrix() { memset(ma,0,sizeof(ma)); } bool operator < (Matrix another) const { for(ll i=1;i<=n;i++) { for(ll j=1;j<=n;j++) { if(ma[i][j]<another.ma[i][j]) { return true; } if(ma[i][j]>another.ma[i][j]) { return false; } } } return false; } }a,b; Matrix mul(Matrix a,Matrix b,ll n,ll m,ll k,ll p) { Matrix c; for(ll i=1;i<=n;i++) { for(ll j=1;j<=k;j++) { for(ll h=1;h<=m;h++) { c.ma[i][j]=(c.ma[i][j]+a.ma[i][h]*b.ma[h][j]%p)%p; } } } return c; } Matrix qpow(Matrix a,ll b,ll p,ll n) { Matrix ans; for(ll i=1;i<=n;i++) { ans.ma[i][i]=1; } while(b>0) { if(b&1) { ans=mul(ans,a,n,n,n,p); } b>>=1; a=mul(a,a,n,n,n,p); } return ans; } ll bsgs(Matrix a,Matrix b,ll p,ll n) { map<Matrix,ll>vis; ll k=sqrt(p)+1,i; Matrix sum; for(i=0;i<=k-1;i++) { b=(i==0)?b:mul(b,a,n,n,n,p); vis[b]=i; } a=qpow(a,k,p,n); for(i=1;i<=n;i++) { sum.ma[i][i]=1; } for(i=0;i<=k;i++) { sum=(i==0)?sum:mul(sum,a,n,n,n,p); if(vis.find(sum)!=vis.end()) { if(i*k-vis[sum]>=0) { return i*k-vis[sum]; } } } return -1; } int main() { ll p,i,j; cin>>n>>p; for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { cin>>a.ma[i][j]; a.ma[i][j]%=p; } } for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { cin>>b.ma[i][j]; b.ma[i][j]%=p; } } cout<<bsgs(a,b,p,n)<<endl; return 0; }
luogu P4387 【深基15.习9】验证栈序列
-
简单的栈模拟。
点击查看代码
int a[100001],b[100001]; int main() { int q,n,r,i,j; cin>>q; for(i=1;i<=q;i++) { cin>>n; stack<int>s; r=1; for(j=1;j<=n;j++) { cin>>a[j]; } for(j=1;j<=n;j++) { cin>>b[j]; } for(j=1;j<=n;j++) { s.push(a[j]); while(s.empty()==0&&s.top()==b[r]) { s.pop(); r++; } } if(s.empty()==0) { cout<<"No"<<endl; } else { cout<<"Yes"<<endl; } } return 0; }
CF1331F Elementary!
-
愚人节的题,建议去看官方题解要简化题意。
点击查看代码
string s,v[120]={" ","H","HE","LI","BE","B","C","N","O","F","NE","NA","MG","AL","SI","P","S","CL","AR","K","CA","SC","TI","V","CR","MN","FE","CO","NI","CU","ZN","GA","GE","AS","SE","BR","KR","RB","SR","Y","ZR","NB","MO","TC","RU","RH","PD","AG","CD","IN","SN","SB","TE","I","XE","CS","BA","LA","CE","PR","ND","PM","SM","EU","GD","TB","DY","HO","ER","TM","YB","LU","HF","TA","W","RE","OS","IR","PT","AU","HG","TL","PB","BI","PO","AT","RN","FR","RA","AC","TH","PA","U","NP","PU","AM","CM","BK","CF","ES","FM","MD","NO","LR","RF","DB","SG","BH","HS","MT","DS","RG","CN","NH","FL","MC","LV","TS","OG"}; bool dfs(int x) { for(int i=1;i<=118;i++) { if(s.compare(x,v[i].size(),v[i])==0) { if(x+v[i].size()==s.size()||dfs(x+v[i].size())==true) { return true; } } } return false; } int main() { cin>>s; if(dfs(0)==true) { cout<<"YES"<<endl; } else { cout<<"NO"<<endl; } return 0; }
2.13
闲话
做题纪要
CF656F Ace It!
-
感谢万能的翻译。
点击查看代码
int main() { int ans=0; char c; while(cin>>c) { if(c=='A') { ans++; } else { if(c=='1') { ans+=10; } else { ans+=c-'0'; } } } cout<<ans<<endl; return 0; }
CF784F Crunching Numbers Just for You
-
每个测试点用时必须在 \(1s\) 以上。
点击查看代码
int a[11]; int main() { int n,i; cin>>n; for(i=1;i<=n;i++) { cin>>a[i]; } i=0; while(1.0*clock()/CLOCKS_PER_SEC<1.5) { i++; } sort(a+1,a+1+n); for(i=1;i<=n;i++) { cout<<a[i]<<" "; } return 0; }
CF656A Da Vinci Powers
-
点击查看代码
int main() { ll n,i,ans=1; cin>>n; for(i=1;i<=n;i++) { ans*=2; if(i==13) { ans-=100; } } cout<<ans<<endl; return 0; }
luogu P1723 高手过愚人节
-
马拉车板子。
点击查看代码
int r[40000001]; string s,t; int main() { int m,n,maxr,id,ans,i,j; cin>>m; for(i=1;i<=m;i++) { cin>>s; t=" #"; maxr=id=ans=0; for(j=0;j<s.size();j++) { t+=s[j]; t+="#"; } n=t.size()-1; for(j=1;j<=n;j++) { r[j]=(j<maxr)?min(r[id-(j-id)],maxr-j):1; while(1<=j-r[j]&&j+r[j]<=n&&t[j-r[j]]==t[j+r[j]]) { r[j]++; } if(maxr<j+r[j]) { maxr=j+r[j]; id=j; } } for(j=1;j<=n;j++) { ans=max(ans,r[j]-1); } cout<<ans<<endl; } return 0; }
luogu P9606 [CERC2019] ABB
-
多倍经验: UVA11475 Extend to Palindrome | SP4103 EPALIN - Extend to Palindrome
-
等价于将原字符串 \(S\) 分成 \(A,B\) 两部分满足 \(A+B=S\) ,使得 \(B\) 为回文串,求 \(|S|-\max \{ |B| \}\) 。
-
输出方案时,设 \(A\) 的反串为 \(A'\) ,有 \(A+B+A'=S+A'\) 即为所求。
点击查看代码
int r[1300001]; string s,t=" #"; int main() { int lens,n,maxr=0,id=0,ans=0,i; cin>>lens>>s; for(i=0;i<s.size();i++) { t+=s[i]; t+='#'; } n=t.size()-1; for(i=1;i<=n;i++) { r[i]=(i<maxr)?min(r[id-(i-id)],maxr-i):1; while(1<=i-r[i]&&i+r[i]<=n&&t[i-r[i]]==t[i+r[i]]) { r[i]++; } if(maxr<i+r[i]) { maxr=i+r[i]; id=i; } if(i+r[i]-1==n) { ans=r[i]-1; break; } } cout<<lens-ans<<endl; return 0; }
UVA1328 Period
-
多倍经验: SP263 PERIOD - Period
-
记得对循环节数量 \(>1\) 进行特判。
点击查看代码
int nxt[10000002]; char s[1000002]; int main() { int n,cnt=0,i,j; while(cin>>n) { if(n==0) { break; } else { cin>>(s+1); cnt++; cout<<"Test case #"<<cnt<<endl; for(i=2,nxt[1]=j=0;i<=n;i++) { while(j>=1&&s[i]!=s[j+1]) { j=nxt[j]; } j+=(s[i]==s[j+1]); nxt[i]=j; if(i%(i-nxt[i])==0&&i/(i-nxt[i])>=2) { cout<<i<<" "<<i/(i-nxt[i])<<endl; } } cout<<endl; } } return 0; }
UVA12467 Secret Word
SP34020 ADAPET - Ada and Pet
2.14
闲话
做题纪要
CF1200E Compress Words
-
从贪心的角度分析,我们发现 \(KMP\) 的最大匹配长度不会超过待拼接串的长度,故对 \(ans_{|ans|-min(|S|,|ans|)+1 \sim |ans|}\) 与 \(S_{1 \sim |S|}\) 进行匹配即可。然后进行拼接即可。
点击查看代码
int nxt[1000002]; char s[1000002],ans[1000002]; int main() { int n,m,i,j,k,lenans; cin>>m>>(ans+1); lenans=strlen(ans+1); for(k=2;k<=m;k++) { cin>>(s+1); n=strlen(s+1); for(i=2,nxt[1]=j=0;i<=n;i++) { while(j>=1&&s[i]!=s[j+1]) { j=nxt[j]; } j+=(s[i]==s[j+1]); nxt[i]=j; } for(i=lenans-min(lenans,n)+1,j=0;i<=lenans;i++) { while(j>=1&&ans[i]!=s[j+1]) { j=nxt[j]; } j+=(ans[i]==s[j+1]); } for(i=j+1;i<=n;i++) { lenans++; ans[lenans]=s[i]; } } for(i=1;i<=lenans;i++) { cout<<ans[i]; } return 0; }
CF471D MUH and Cube Walls
-
对 \(a,b\) 的差分数组跑一遍 \(KMP\) 即可。
-
记得对 \(w=1\) 进行特判。
点击查看代码
int a[200002],b[200002],s1[200002],s2[200002],nxt[200002]; int main() { int n,m,i,j,ans=0; cin>>n>>m; for(i=1;i<=n;i++) { cin>>a[i]; } for(i=1;i<=n-1;i++) { s1[i]=a[i+1]-a[i]; } for(i=1;i<=m;i++) { cin>>b[i]; } for(i=1;i<=m-1;i++) { s2[i]=b[i+1]-b[i]; } if(m==1) { ans=n; } else { for(i=2,nxt[1]=j=0;i<=m-1;i++) { while(j>=1&&s2[i]!=s2[j+1]) { j=nxt[j]; } j+=(s2[i]==s2[j+1]); nxt[i]=j; } for(i=1,j=0;i<=n-1;i++) { while(j>=1&&s1[i]!=s2[j+1]) { j=nxt[j]; } j+=(s1[i]==s2[j+1]); if(j==m-1) { ans++; j=nxt[m-1]; } } } cout<<ans<<endl; return 0; }
[ABC339F] Product Equality
-
双哈希板子。
点击查看代码
#define ll __int128_t const ll mod1=1000000000000000003,mod2=100000000000001093,base=10; map<ll,ll>vis[4]; ll a[1002][4][1002],len[1002],jc[4][1002]; char s[1002]; ll read() { ll x=0,f=1; char c=getchar(); while(c>'9'||c<'0') { if(c=='-') { f=-1; } c=getchar(); } while('0'<=c&&c<='9') { x=x*10+c-'0'; c=getchar(); } return x*f; } void write(ll x) { if(x<0) { putchar('-'); x=-x; } if(x>9) { write(x/10); } putchar((x%10)+'0'); } void sx_hash(char s[],ll a[],ll len,ll mod) { for(ll i=0;i<=len;i++) { a[i]=(i==0)?0:((a[i-1]*base%mod+s[i]-'0')%mod); } } ll ask_hash(ll a[],ll jc[],ll l,ll r,ll mod) { return (a[r]-a[l-1]*jc[r-l+1]%mod+mod)%mod; } int main() { ll n,ans=0,i,j; n=read(); for(i=0;i<=1000;i++) { jc[1][i]=(i==0)?1:(jc[1][i-1]*base%mod1); jc[2][i]=(i==0)?1:(jc[2][i-1]*base%mod2); jc[3][i]=(i==0)?1:(jc[3][i-1]*base%mod2); } for(i=1;i<=n;i++) { cin>>(s+1); len[i]=strlen(s+1); sx_hash(s,a[i][1],len[i],mod1); vis[1][ask_hash(a[i][1],jc[1],1,len[i],mod1)]++; sx_hash(s,a[i][2],len[i],mod2); vis[2][ask_hash(a[i][2],jc[2],1,len[i],mod2)]++; } for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { if(vis[1].find(ask_hash(a[i][1],jc[1],1,len[i],mod1)*ask_hash(a[j][1],jc[1],1,len[j],mod1)%mod1)!=vis[1].end()&&vis[2].find(ask_hash(a[i][2],jc[2],1,len[i],mod2)*ask_hash(a[j][2],jc[2],1,len[j],mod2)%mod2)!=vis[2].end()) { if(vis[1][ask_hash(a[i][1],jc[1],1,len[i],mod1)*ask_hash(a[j][1],jc[1],1,len[j],mod1)%mod1]==vis[2][ask_hash(a[i][2],jc[2],1,len[i],mod2)*ask_hash(a[j][2],jc[2],1,len[j],mod2)%mod2]) { ans+=vis[1][ask_hash(a[i][1],jc[1],1,len[i],mod1)*ask_hash(a[j][1],jc[1],1,len[j],mod1)%mod1]; } } } } write(ans); return 0; }
[ABC331F] Palindrome Query
-
若一个字符串为回文串,则原串哈希值等于其反串的哈希值。
-
线段树维护原串和反串的哈希值即可。
点击查看代码
const ll base=13331; ull jc[5000001]; char s[5000001]; struct SegmentTree { ull l,r,sum[2],len; }tree[5000001]; ull lson(ull x) { return x*2; } ull rson(ull x) { return x*2+1; } void pushup(ull rt) { tree[rt].sum[0]=tree[lson(rt)].sum[0]*jc[tree[rson(rt)].len]+tree[rson(rt)].sum[0]; tree[rt].sum[1]=tree[rson(rt)].sum[1]*jc[tree[lson(rt)].len]+tree[lson(rt)].sum[1]; tree[rt].len=tree[lson(rt)].len+tree[rson(rt)].len; } void build(ull rt,ull l,ull r) { tree[rt].l=l; tree[rt].r=r; if(l==r) { tree[rt].sum[0]=tree[rt].sum[1]=s[l]; tree[rt].len=1; return ; } ull mid=(l+r)/2; build(lson(rt),l,mid); build(rson(rt),mid+1,r); pushup(rt); } void update(ull rt,ull pos,ull val) { if(tree[rt].l==tree[rt].r) { tree[rt].sum[0]=tree[rt].sum[1]=val; return ; } ull mid=(tree[rt].l+tree[rt].r)/2; if(pos<=mid) { update(lson(rt),pos,val); } else { update(rson(rt),pos,val); } pushup(rt); } pair<ull,ull> query1(ull rt,ull l,ull r) { if(l<=tree[rt].l&&tree[rt].r<=r) { return make_pair(tree[rt].sum[0],tree[rt].len); } ull mid=(tree[rt].l+tree[rt].r)/2; pair<ull,ull>lans=make_pair(0,0),rans=make_pair(0,0); if(l<=mid) { lans=query1(lson(rt),l,r); } if(r>mid) { rans=query1(rson(rt),l,r); } return make_pair(lans.first*jc[rans.second]+rans.first,lans.second+rans.second); } pair<ull,ull> query2(ull rt,ull l,ull r) { if(l<=tree[rt].l&&tree[rt].r<=r) { return make_pair(tree[rt].sum[1],tree[rt].len); } ull mid=(tree[rt].l+tree[rt].r)/2; pair<ull,ull>lans=make_pair(0,0),rans=make_pair(0,0); if(l<=mid) { lans=query2(lson(rt),l,r); } if(r>mid) { rans=query2(rson(rt),l,r); } return make_pair(rans.first*jc[lans.second]+lans.first,lans.second+rans.second); } int main() { ull n,m,l,r,pd,i; char c; cin>>n>>m>>(s+1); for(i=0;i<=n;i++) { jc[i]=(i==0)?1:(jc[i-1]*base); } build(1,1,n); for(i=1;i<=m;i++) { cin>>pd>>l; if(pd==1) { cin>>c; update(1,l,c); } if(pd==2) { cin>>r; if(query1(1,l,r).first==query2(1,l,r).first) { cout<<"Yes"<<endl; } else { cout<<"No"<<endl; } } } return 0; }
本文来自博客园,作者:hzoi_Shadow,原文链接:https://www.cnblogs.com/The-Shadow-Dragon/p/18013803,未经允许严禁转载。
版权声明:本作品采用 「署名-非商业性使用-相同方式共享 4.0 国际」许可协议(CC BY-NC-SA 4.0) 进行许可。