ABC367

A

void solve(){
    int a,b,c;cin>>a>>b>>c;
    if(b>c){
        if(a>=b&&a<24||a>=0&&a<c)cout<<"No"<<endl;else cout<<"Yes"<<endl;
    }else{
        if(0<=a&&a<b||a>=c)cout<<"Yes"<<endl;else cout<<"No"<<endl;
    }
}

B

void solve(){
    string s;cin>>s;
    int flag=1;
    for(int i=0;i<s.size();i++){
        if(flag&&s[i]!='.'){
            cout<<s[i];
        }else{
            int ok=0;
            for(int j=i;j<s.size();j++){
                if(s[j]=='.')continue;
                if(s[j]!='0')ok=1;
            }
            if(!ok)break;
            else cout<<s[i];
        }
        if(s[i]=='.')flag=0;
    }

}

C

int a[maxn];
int n,k;
vector<int>res;
void dfs(int cur,int sum){
    if(cur>n){
        if(sum%k!=0)return;
        for(int x:res)cout<<x<<' ';
        cout<<endl;return;
    }
    for(int i=1;i<=a[cur];i++){
        res.pb(i);
        dfs(cur+1,sum+i);
        res.pop_back();
    }
}
void solve(){
    cin>>n>>k;
    rep(i,1,n)cin>>a[i];
    dfs(1,0);
}

D

题意:给定一个有n个点的环,以及点之间的距离,求点对dis(s,t)(s!=t)%m=0的数量
思路:
枚举点t,显然有前缀和pre_t-pre_(s-1)=dis(s,t)
进而有dis(s,t)%m=0 - > pre_t%m=pre_(s-1)%m
显然开个桶每次记录一下pre_t%m即可

这是s->t的情况

若t->s

我们有dis(s,t)=len(环长)-(pre_t-pre_(s-1))
dis(t,s)%m=0 - > ( pre_t - len)%m = pre_(s-1)% m
其中pre_(s-1)和我们上面记录的相同

int tot[maxn];
void solve(){
    int n,m;cin>>n>>m;
    vector<int>a(n+1);
    rep(i,1,n)cin>>a[i];
    int len=0;
    rep(i,1,n)len+=a[i];
    int ans=0;
    vector<int>pre(n+1);
    rep(i,1,n){
        pre[i]=pre[i-1]+a[i];
        ans+=(tot[pre[i]%m]+tot[(pre[i]%m-len%m+m)%m]);
        tot[pre[i]%m]++;
    }
    cout<<ans<<endl;
}

E

题意:给定数组X,数组A,每次操作同时使A_i:=A[X_i],求k次操作后的数组A
思路:发现好像是一些基环树,但不用图论做
考虑倍增,anc[i][j]指的是i位置进行2^j次操作后的数组下标
显然anc[i][0]=X[i]
初始位置ans[i]=i
把k拆分成二进制,每次倍增跳转即可

int anc[maxn][65];
void solve(){
    int n,k;cin>>n>>k;
    vector<int>x(n+1);
    vector<int>a(n+1);
    rep(i,1,n)cin>>x[i];
    rep(i,1,n)cin>>a[i];
    if(k==0){
        rep(i,1,n){
            cout<<a[i]<<' ';
        }
        cout<<endl;
        return;
    }

    rep(i,1,n){
        anc[i][0]=x[i];
    }

    {
        for(int i=1;i<=64;i++){
            for(int j=1;j<=n;j++){
                anc[j][i]=anc[anc[j][i-1]][i-1];
            }
        }

    }
    vector<int>ans(n+1);
    rep(i,1,n)ans[i]=i;
    for(int i=62;i>=0;i--){
        if((1ll<<i)&k){
            rep(j,1,n){
                ans[j]=anc[ans[j]][i];
            }
        }
    }
    rep(i,1,n){
        cout<<a[ans[i]]<<' ';
    }
    cout<<endl;
}

F

题意:给定两个数组A和B,q次询问
每次给定l,r,L,R,询问是否能使A[l....r]的数重排变为B[L...R]
思路:
简单哈希,但是前缀
显然如果用异或哈希可以被出现不同偶数次的数hack掉
哈希怎么说哈希

ull h[maxn];
void solve(){
    int n,q;cin>>n>>q;
    rep(i,1,n){
        h[i]=rnd();
    }
    vector<int>a(n+1);rep(i,1,n)cin>>a[i];
    vector<int>b(n+1);rep(i,1,n)cin>>b[i];
    vector<ull>prea(n+1);rep(i,1,n)prea[i]=prea[i-1]+h[a[i]];
    vector<ull>preb(n+1);rep(i,1,n)preb[i]=preb[i-1]+h[b[i]];

    while(q--){
        int l,r,L,R;cin>>l>>r>>L>>R;
        if(R-r!=L-l){
            cout<<"No"<<endl;continue;
        }
        if((prea[r]-prea[l-1])^(preb[R]-preb[L-1]))cout<<"No"<<endl;
        else cout<<"Yes"<<endl;
    }
}
posted @ 2025-07-24 23:02  Marinaco  阅读(9)  评论(0)    收藏  举报
//雪花飘落效果