AtCoder Beginner Contest 446题解
怎么自己现在这么区。
D - Max Straight
区完了,这么简单的题,直接拿map做就行了,结果我在哪里考虑排序,然后一段一段取lis。糖丸一个。
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
unordered_map<int, int> d;
int ans = 0;
for (int i = 0; i < n; i++) {
int ai;
cin >> ai;
d[ai] = max(d[ai], d[ai - 1] + 1);
ans = max(ans, d[ai]);
}
cout << ans << endl;
}
E - Multiple-Free Sequences
简单数学题
int ans;
void dfs(int x,int y){
if(x == 0 || y == 0){
bad[x][y] = true;
return;
}
if(vis[x][y]) return;//访问过的节点,表示合法
vis[x][y] = true;
dfs(y % m,(a * y + b * x) % m);//访问后继
bad[x][y] = bad[y % m][(a * y + b * x) % m];//继承后继是否合法的状态
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> m >> a >> b;
for(int x = 1;x < m;x++){
for(int y = 1;y < m;y++){
if(!vis[x][y]) dfs(x,y);//剪枝
ans += !bad[x][y];//累计答案
}
}
cout << ans;
}
F - Reachable Set 2
挺好一题,首先是如何判断可否实现。我们完全可以利用求最短路的方法来求得。然后再求一个前缀最大值。
至于删除的点数,一个一个的往后求就行了。
int n,m;
vector<int>g[N];
priority_queue<pii,vector<pii>,greater<pii> >q;
bool vis[N];
int dis[N],pre[N];
void djs(){
memset(dis,0x3f,sizeof dis);
dis[1]=1;
q.push({1,1});
while(q.size()){
int u=q.top().second;q.pop();
if(vis[u])continue;
vis[u]=1;
for(auto v:g[u]){
if(dis[v]>max(dis[u],v)){
dis[v]=max(dis[u],v);
q.push({dis[v],v});
}
}
}
}
map<pii,int>mp;
bool fg[N];
void solve(){
cin>>n>>m;
int u,v;
up(i,1,m){
cin>>u>>v;
if(u==v)continue;
//if(u>v)swap(u,v);
if(mp[{u,v}])continue;
g[u].push_back(v);
mp[{u,v}]=1;
}
//up(i,1,n)sort(g[i].begin(),g[i].end());
djs();
up(i,1,n){
pre[i]=max(pre[i-1],dis[i]);
}
int ans=0;
up(i,1,n){
bool flag=0;
for(auto x:g[i]){
if(!fg[x]){
fg[x]=1;
ans++;
}
//if(fg[i])flag=1;
}
if(fg[i])ans--;
fg[i]=1;
if(pre[i]>i)cout<<-1<<endl;
else{
cout<<ans<<endl;
}
}
}
signed main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
int T=1;
while(T--){
solve();
}
return 0;
}

浙公网安备 33010602011771号