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

lyrrr發表於2024-10-10

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();
}

相關文章