[题解]AtCoder Beginner Contest 411(ABC411) A~D
因为要准备考试所以补题会晚些。(#><)
A - Required Length
输出Yes\(\iff |s|\ge n\)。
时间复杂度\(O(1)\)。
点击查看代码
#include<bits/stdc++.h>
using namespace std;
string s;
int n;
signed main(){
cin>>s>>n;
cout<<(s.size()>=n?"Yes":"No");
return 0;
}
B - Distance Table
照题意统计并输出即可,见代码。
时间复杂度\(O(n^2)\)。
点击查看代码
#include<bits/stdc++.h>
#define N 55
using namespace std;
int n,a[N];
signed main(){
cin>>n;
for(int i=1;i<n;i++) cin>>a[i];
for(int i=1;i<n;i++){
int sum=0;
for(int j=i;j<n;j++) sum+=a[j],cout<<sum<<" ";
cout<<"\n";
}
return 0;
}
C - Black Intervals
显然,对于\(i\)这一位的反转操作:
- 如果是\(0\)变\(1\):
- 如果与\(i\)相邻的位置都是\(0\),答案\(+1\)。
- 如果与\(i\)相邻的位置恰有\(1\)个\(1\),答案不变。
- 如果与\(i\)相邻的位置恰有\(2\)个\(1\),答案\(-1\)。
- 如果是\(1\)变\(0\),就将前一种情况对答案的贡献取相反数。
时间复杂度\(O(q)\)。
点击查看代码
#include<bits/stdc++.h>
#define N 500010
using namespace std;
int n,q,ans;
bitset<N> v;
signed main(){
cin>>n>>q;
while(q--){
int x;
cin>>x;
v[x]=!v[x];
ans+=(v[x]?-1:1)*(v[x-1]+v[x+1]-1);
cout<<ans<<"\n";
}
return 0;
}
D - Conflict 2
字符串的赋值是线性复杂度的,因此直接暴力赋值是不可行的。只需要构造“让\(S\)在两台机器之间来回传递”的数据就可以卡成\(O(n|S|)\)。
赛时思路
建立Trie树求解。
让第\(i\)台PC机都记录\(num[i]\),表示其拥有的字符串在Trie上的节点编号。追加字符时直接从\(num[i]\)开始新建节点;赋值操作直接对\(num\)进行即可。
输出答案,仅需一遍DFS从Trie树上找到服务器的\(num\),输出途经的字符即可。
时间复杂度\(O(n+|S|)\),空间复杂度\(O(n|\Sigma|)\)。其中\(|\Sigma|=26\),为字符集大小。
点击查看代码
#include<bits/stdc++.h>
#define N 200010
#define L 1000010
#define C 26
using namespace std;
int n,q,cur,num[N],tr[L][C],idx;
string s,a[N];
void ins(int &p,string& s){
for(int i:s){
int c=i-'a';
if(!tr[p][c]) tr[p][c]=++idx;
p=tr[p][c];
}
}
bool dfs(int p){
if(p==cur) return 1;
for(int i=0;i<C;i++)
if(tr[p][i]&&dfs(tr[p][i]))
return s+=(i+'a'),1;
return 0;
}
signed main(){
cin>>n>>q;
for(int i=1,op,p;i<=q;i++){
cin>>op;
if(op==1) cin>>p,num[p]=cur;
else if(op==2) cin>>p>>s,ins(num[p],s);
else cin>>p,cur=num[p];
}
s.clear(),dfs(0);
reverse(s.begin(),s.end()),cout<<s<<"\n";
return 0;
}
浙公网安备 33010602011771号