AtCoder Beginner Contest 260 D E F
D - Draw Your Cards
题意: 按给定顺序对一系列卡牌进行堆叠,设当前操作数为x,如果现有堆的最上面存在一个数比x大且最接近x,那么就将x叠上去,叠完判断这一堆的的卡牌数是否等于k,是的话则清空该堆。如果现有堆不存在这个数,那么就另起一堆。
思路: 用set模拟即可,每一堆中的卡牌都会有相同的一个值tot,我们用vis数组记录下来,然后下次进行堆叠的时候即可取出堆顶的tot复制给当前的这个数。
代码
#include<bits/stdc++.h>
#define ll long long
#define endl '\n'
using namespace std;
const int N=5e5+5;
const ll inf=0x3f3f3f3f;
ll n,m,x,y;
int a[N];
void solve(){
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
}
set<int>s;
map<int,int>vis;
int tot=0;
map<int,int>cnt;
map<int,int>ans;
for(int i=1;i<=n;i++){
auto it=s.lower_bound(a[i]);
if(it==s.end()){
s.insert(a[i]);
vis[a[i]]=++tot;
cnt[tot]++;
if(cnt[tot]==m){
s.erase(a[i]);
ans[tot]=i;
}
// cout<<i<<" insert"<<endl;
}
else {
s.insert(a[i]);
int tag=vis[*it];
s.erase(it);
vis[a[i]]=tag;
cnt[tag]++;
if(cnt[tag]==m){
s.erase(a[i]);
ans[tag]=i;
}
}
}
for(int i=1;i<=n;i++){
if(ans[vis[i]])cout<<ans[vis[i]]<<endl;
else cout<<-1<<endl;
}
}
signed main(){
ios::sync_with_stdio(0);cin.tie(0);
int T=1;
// cin>>T;
while(T--){solve();}
}
E - At Least One
题意: 给出n对数\(a_ib_i\),问1到m中有多少个好子串
好子串的定义是,对于每一对\(a_ib_i\),至少要有一个出现的串中。
思路: 类似于滑动窗口,利用双指针处理出适配左右端点l,r
可以算出当前区间对答案的贡献(左端点不动,右端点向右移动仍然是合法串,所以就有一个最短的串和最长的串的长度),利用差分对区间进行修改。
代码
#include<bits/stdc++.h>
#define ll long long
#define endl '\n'
using namespace std;
const int N=5e5+5;
const ll inf=0x3f3f3f3f;
signed main(){
int n,m;cin>>n>>m;
vector<int>a(n),b(n);
for(int i=0;i<n;i++){
cin>>a[i]>>b[i];
}
vector<vector<int>>ind(m+1);
for(int i=0;i<n;i++){
ind[a[i]].push_back(i);
ind[b[i]].push_back(i);
}
vector<int>cnt(n),ans(m+5);
int num=n;
for(int i=1,j=1;i<=m;){
while(j<=m&&num!=0){
for(auto x:ind[j]){
if(cnt[x]==0)num--;
cnt[x]++;
}
j++;
}
if(num!=0)break;
ans[j-i]++;
ans[(m+1-i)+1]--;
for(auto x:ind[i]){
cnt[x]--;
if(cnt[x]==0)num++;
}
i++;
}
for(int i=1;i<=m;i++){
ans[i]+=ans[i-1];
cout<<ans[i]<<" ";
}
cout<<'\n';
}
F - Find 4-cycle
题意: 给定两个集合S,T,有m条边相连,每一条边中的其中一个点属于S,另一个属于T。问是否存在一个环,长度为4,存在输出每个点,不存在则-1。
思路: 可以注意到集合T中的点只有3000个,那么我们可以去\(n^2\)的枚举任意两个点u,v,判断是否存在集合S中的两个点相连。
代码
#include <bits/stdc++.h>
#define endl '\n';
#define ll long long
using namespace std;
const int N = 5e5 + 5;
int a[N],b[N],p[N];
int dp[3005][3005];
vector<int>G[N];
void solve() {
memset(dp,-1,sizeof(dp));
int s, t, m;
cin >> s >> t >> m;
for(int i = 0; i < m; i ++) {
int u, v;
cin >> u >> v;
G[u].push_back(v-s);
}
for(int i =1; i <= s; i ++) {
for(auto u : G[i]){
for(auto v : G[i]){
if(u == v)continue;
if(dp[u][v] != -1){
cout << i << " " << dp[u][v] << " ";
cout<< u + s << " " << v + s << '\n';
return ;
}
dp[u][v] = i;
}
}
}
cout << -1 << endl;
}
int main() {
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int T = 1;
// cin >> T;
while(T --) { solve(); }
}