很 Easy 一場,共計用時 \(34\) min
A
const int N=1000100;
signed main(){
string s;cin>>s;
int cnt=0;
int n=s.size();
if(s[n-1]=='0'&&s[n-2]=='0'&&s[n-3]=='0'){
s.pop_back();
s.pop_back();
s.pop_back();
s.pop_back();
}else{
while(s.back()=='0')
s.pop_back();
}
cout<<s<<'\n';
}
B
signed main(){
string s;cin>>s;
int cnt=0;
int n=s.size();
if(s[n-1]=='0'&&s[n-2]=='0'&&s[n-3]=='0'){
s.pop_back();
s.pop_back();
s.pop_back();
s.pop_back();
}else{
while(s.back()=='0')
s.pop_back();
}
cout<<s<<'\n';
}
C
發現數的範圍很小,所以直接 dfs 然後判斷是否合法即可。
const int N=1000100;
int a[N],b[N],n,k;
void dfs(int dep){
if(dep==n+1){
int s=0;
F(i,1,n)s+=b[i];
if(s%k==0){
F(i,1,n)cout<<b[i]<<' ';
cout<<'\n';
}
return;
}
F(i,1,a[dep]){
b[dep]=i;
dfs(dep+1);
}
}
signed main(){
cin>>n>>k;
F(i,1,n)cin>>a[i];
dfs(1);
}
D
考慮經典套路破換成鏈,然後雙指標掃描合法區間,即求在合法區間內和在模 \(M\) 意義下同餘 \(0\) 的方案數。記錄每一個字首和出現次數即可。時間複雜度為 \(O(n)\) 但是我寫醜了所以是 \(O(n\log n)\) 的。
const int N=1000100;
int a[N],s[N];
signed main(){
int n,m;cin>>n>>m;
F(i,1,n)cin>>a[i];
F(i,1,n-1)a[i+n]=a[i];
F(i,1,n+n-1)s[i]=(s[i-1]+a[i])%m;
map<int,int>mp;
int cnt=0;
F(i,1,n+n-1){
if(i>n)--mp[s[i-n]];
cnt+=(mp[s[i]]);
if(i<=n)++mp[s[i]];
// cout<<i<<": "<<s[i]<<' '<<mp[s[i]]-1<<'\n';
}
cout<<cnt<<'\n';
}
E
經典套路,將每一個點分開考慮。設 \(f_{i,x}\) 表示 \(x\) 點連續執行 \(2^i\) 次操作之後到達的點,因此 \(O(\log n)\) 時間複雜度內暴力跳得每一個點的答案即可。時間複雜度為 \(O(n\log n)\)。注意陣列不要開小要不然會像我一樣調 15min。
const int N=200100;
int x[N],a[N],f[63][N],b[N];
int get(int x,int y){
int t=x;
F(i,0,62)
if(y>>i&1)
x=f[i][x];
return x;
}
signed main(){
int n,k;cin>>n>>k;
F(i,1,n)cin>>x[i];
F(i,1,n)cin>>a[i];
if(k==0){
F(i,1,n)cout<<a[i]<<' ';
cout<<'\n';
return 0;
}
F(i,1,n)f[0][i]=x[i];
F(i,1,62)
F(j,1,n)f[i][j]=f[i-1][f[i-1][j]];
F(i,1,n)
cout<<a[get(i,k)]<<' ';
cout<<'\n';
}
F
參見原神數學測試本上第 \(35\) 頁的 DS 第 \(11\) 題
考慮給兩個序列都做一個和位置無關的雜湊,然後建兩棵線段樹,計算其雜湊值是否全都一樣即可。時間複雜度為 \(O(n\log n)\)。
因為這一類雜湊的衝突機率極大,因此考慮多寫幾個雜湊,或者給每一個值隨機賦權即可。
const int N=1000100;
int a[N],b[N];
namespace _1{
using ull=unsigned long long;
const int m1=998244353,m2=1e9+7;
struct qwq{
int l,r,sum,xr,s4m1,s4m2;
ull s2,s3;
void init(int p){
l=r=p;
sum=xr=a[p];
s2=a[p]*a[p];
s3=a[p]*a[p]*a[p];
s4m1=a[p]*a[p]%m1*a[p]%m1*a[p]%m1;
s4m2=a[p]*a[p]%m2*a[p]%m2*a[p]%m2;
}
}z[N<<2];
qwq operator+(const qwq&l,const qwq &r){
return {l.l,r.r,l.sum+r.sum,l.xr^r.xr,(l.s4m1+r.s4m1)%m1,(l.s4m2+r.s4m2)%m2,l.s2+r.s2,l.s3+r.s3};
}
void build(int l,int r,int rt){
if(l==r)return z[rt].init(l);
int mid=l+r>>1;
build(l,mid,rt<<1);
build(mid+1,r,rt<<1|1);
z[rt]=z[rt<<1]+z[rt<<1|1];
}
qwq qu(int l,int r,int rt,int ll,int rr){
if(ll<=l&&r<=rr)return z[rt];
int mid=l+r>>1;
if(ll<=mid&&mid<rr)return qu(l,mid,rt<<1,ll,rr)+qu(mid+1,r,rt<<1|1,ll,rr);
if(ll<=mid)return qu(l,mid,rt<<1,ll,rr);
return qu(mid+1,r,rt<<1|1,ll,rr);
}
}
namespace _2{
using ull=unsigned long long;
const int m1=998244353,m2=1e9+7;
struct qwq{
int l,r,sum,xr,s4m1,s4m2;
ull s2,s3;
void init(int p){
l=r=p;
sum=xr=b[p];
s2=b[p]*b[p];
s3=b[p]*b[p]*b[p];
s4m1=b[p]*b[p]%m1*b[p]%m1*b[p]%m1;
s4m2=b[p]*b[p]%m2*b[p]%m2*b[p]%m2;
}
}z[N<<2];
qwq operator+(const qwq&l,const qwq &r){
return {l.l,r.r,l.sum+r.sum,l.xr^r.xr,(l.s4m1+r.s4m1)%m1,(l.s4m2+r.s4m2)%m2,l.s2+r.s2,l.s3+r.s3};
}
void build(int l,int r,int rt){
if(l==r)return z[rt].init(l);
int mid=l+r>>1;
build(l,mid,rt<<1);
build(mid+1,r,rt<<1|1);
z[rt]=z[rt<<1]+z[rt<<1|1];
}
qwq qu(int l,int r,int rt,int ll,int rr){
if(ll<=l&&r<=rr)return z[rt];
int mid=l+r>>1;
if(ll<=mid&&mid<rr)return qu(l,mid,rt<<1,ll,rr)+qu(mid+1,r,rt<<1|1,ll,rr);
if(ll<=mid)return qu(l,mid,rt<<1,ll,rr);
return qu(mid+1,r,rt<<1|1,ll,rr);
}
}
signed main(){
int n,q;cin>>n>>q;
F(i,1,n)cin>>a[i];
F(i,1,n)cin>>b[i];
_1::build(1,n,1);
_2::build(1,n,1);
while(q--){
int l,r,ll,rr;
cin>>l>>r>>ll>>rr;
if(r-l+1==rr-ll+1){
auto f1=_1::qu(1,n,1,l,r);
auto f2=_2::qu(1,n,1,ll,rr);
if(f1.sum==f2.sum&&f1.xr==f2.xr&&f1.s2==f2.s2&&f1.s3==f2.s3&&f1.s4m1==f2.s4m1&&f1.s4m2==f2.s4m2)cout<<"Yes\n";
else cout<<"No\n";
}else cout<<"No\n";
}
}