Codeforces Round 977 (Div. 2)(B-C2)

B:

感觉最近几题都用了这种继承的思想。然后就把n方转化为一个递推的问题。
我写了一个跟题解不同的做法是取同余也挺巧妙的。

#include<bits/stdc++.h>
using namespace std;
#define CI const int&
#define int long long
const int maxn=2e5+10;
int a[maxn],vis[maxn],cnt[maxn];
void solve(){
    int n,x;cin>>n>>x;
    for(int i=0;i<=n;i++)vis[i]=0,cnt[i]=0;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        if(a[i]<=n)vis[a[i]]++;
    }
    for(int i=0;i<=n;i++){
        if(vis[i]==0&&cnt[i%x]==0){
            return cout<<i<<endl,void();
        }
        if(vis[i])vis[i]--;
        else cnt[i%x]--;
        if(vis[i]>0)cnt[i%x]+=vis[i];
    }
}
signed main(){
    int t;cin>>t;while(t--)solve();
}

C1:

甚至不需要发现性质也能写的贪心。

C2:

性质其实就是找一个值在b中第一次出现的顺序是否与a排列顺序相符。
由此很容易发现是严格递增的,然后维护手段也很多。线段树写起来很简单,也算是权值线段树了。
就是得套个set。然后ai,bi还有下标的关系要考虑清楚,还有删除操作。

#include<bits/stdc++.h>
using namespace std;
#define CI const int&
#define int long long
#define ls(x) (x*2)
#define rs(x) (x*2+1)
const int maxn=1e6+10;
int a[maxn],b[maxn],c[maxn],n,m,q;
int mx[maxn],mn[maxn],t[maxn];
set<int>st[maxn];
void push_up(int p){
    mx[p]=max(mx[ls(p)],mx[rs(p)]);
    mn[p]=min(mn[ls(p)],mn[rs(p)]);
    if(t[ls(p)]&&t[rs(p)]&&mx[ls(p)]<mn[rs(p)])t[p]=1;
    else t[p]=0;
}
void upd(int p,int l,int r,int q,int k){
    //cout<<l<<r<<endl;
    if(l==r){
        mx[p]=mn[p]=k;t[p]=1;
        return;
    }
    int mid=(l+r)/2;
    if(q<=mid)upd(ls(p),l,mid,q,k);
    else upd(rs(p),mid+1,r,q,k);
    push_up(p);
    //cout<<p<<' '<<t[p]<<'k'<<endl;
}
void solve(){
    cin>>n>>m>>q;
    for(int i=1;i<=n;i++)st[i].clear();
    for(int i=1;i<=n;i++){
        cin>>a[i],c[a[i]]=i;
        if(st[a[i]].size()==0)st[a[i]].insert(m+i);
    }
    for(int i=1;i<=m;i++){
        cin>>b[i];st[b[i]].insert(i);
    }
    set<int>::iterator it;
    for(int i=1;i<=n;i++){
        it=st[a[i]].begin(),upd(1,1,n,c[a[i]],*it);
    }
    if(t[1])cout<<"Ya"<<endl;
    else cout<<"TIDAK"<<endl;
    while(q--){
        int i,j;cin>>i>>j;
        st[b[i]].erase(i);//
        upd(1,1,n,c[b[i]],*st[b[i]].begin());
        b[i]=j;
        st[j].insert(i);
        it=st[j].begin();
        upd(1,1,n,c[j],*it);
        if(t[1])cout<<"Ya"<<endl;
        else cout<<"TIDAK"<<endl;
    }
}
signed main(){
    int t;cin>>t;while(t--)solve();
}
posted @ 2024-10-10 10:13  lyrrr  阅读(23)  评论(0)    收藏  举报