8.29NOIP Day14模拟赛

T1

有一个Trick是钦定等大的数前面的小后面的大,但是没敢用,就写的特别丑

分类讨论,120次树状数组力大砖飞,这么糖的也是没谁了

#include<bits/stdc++.h>
#define LL long long
#define mod 998244353
#define N 100005
using namespace std;
int x[6][N],num[N*5],n,m,cnt;
int lowbit(int u){return u&-u;}
struct Ig{
    int y[N*5];
    void update(int u){
        for(int i=u;i<=m;i+=lowbit(i))y[i]++;
        return;
    }
    int queryd(int u){
        if(!u)return 0;
        int now=0;
        for(int i=u;i;i-=lowbit(i))now+=y[i];
        return now;
    }
    int queryu(int u){
        if(u>m)return 0;
        return queryd(m)-queryd(u-1);
    }
}T[6];
signed main(){
    scanf("%d",&n);
    for(int i=1;i<=5;i++)for(int j=1;j<=n;j++){
        scanf("%d",&x[i][j]);
        num[++cnt]=x[i][j];
    }
    sort(num+1,num+cnt+1);
    m=unique(num+1,num+cnt+1)-num-1;
    for(int i=1;i<=5;i++)for(int j=1;j<=n;j++){
        x[i][j]=lower_bound(num+1,num+m+1,x[i][j])-num;
        T[i].update(x[i][j]);
    }
    long long ans=0;
    for(int i=1;i<=n;i++){
        ans=(ans+1ll*num[x[1][i]]*T[2].queryu(x[1][i])  %mod*T[3].queryu(x[1][i])  %mod*T[4].queryd(x[1][i]-1)%mod*T[5].queryd(x[1][i]-1))%mod;
        ans=(ans+1ll*num[x[1][i]]*T[2].queryu(x[1][i])  %mod*T[3].queryd(x[1][i]-1)%mod*T[4].queryu(x[1][i])  %mod*T[5].queryd(x[1][i]-1))%mod;
        ans=(ans+1ll*num[x[1][i]]*T[2].queryu(x[1][i])  %mod*T[3].queryd(x[1][i]-1)%mod*T[4].queryd(x[1][i]-1)%mod*T[5].queryu(x[1][i]))%mod;
        ans=(ans+1ll*num[x[1][i]]*T[2].queryd(x[1][i]-1)%mod*T[3].queryu(x[1][i])  %mod*T[4].queryu(x[1][i])  %mod*T[5].queryd(x[1][i]-1))%mod;
        ans=(ans+1ll*num[x[1][i]]*T[2].queryd(x[1][i]-1)%mod*T[3].queryu(x[1][i])  %mod*T[4].queryd(x[1][i]-1)%mod*T[5].queryu(x[1][i]))%mod;
        ans=(ans+1ll*num[x[1][i]]*T[2].queryd(x[1][i]-1)%mod*T[3].queryd(x[1][i]-1)%mod*T[4].queryu(x[1][i])  %mod*T[5].queryu(x[1][i]))%mod;
    }
    for(int i=1;i<=n;i++){
        ans=(ans+1ll*num[x[2][i]]*T[1].queryu(x[2][i]+1)%mod*T[3].queryu(x[2][i])  %mod*T[4].queryd(x[2][i]-1)%mod*T[5].queryd(x[2][i]-1))%mod;
        ans=(ans+1ll*num[x[2][i]]*T[1].queryu(x[2][i]+1)%mod*T[3].queryd(x[2][i]-1)%mod*T[4].queryu(x[2][i])  %mod*T[5].queryd(x[2][i]-1))%mod;
        ans=(ans+1ll*num[x[2][i]]*T[1].queryu(x[2][i]+1)%mod*T[3].queryd(x[2][i]-1)%mod*T[4].queryd(x[2][i]-1)%mod*T[5].queryu(x[2][i]))  %mod;
        ans=(ans+1ll*num[x[2][i]]*T[1].queryd(x[2][i])  %mod*T[3].queryu(x[2][i])  %mod*T[4].queryu(x[2][i])  %mod*T[5].queryd(x[2][i]-1))%mod;
        ans=(ans+1ll*num[x[2][i]]*T[1].queryd(x[2][i])  %mod*T[3].queryu(x[2][i])  %mod*T[4].queryd(x[2][i]-1)%mod*T[5].queryu(x[2][i]))  %mod;
        ans=(ans+1ll*num[x[2][i]]*T[1].queryd(x[2][i])  %mod*T[3].queryd(x[2][i]-1)%mod*T[4].queryu(x[2][i])  %mod*T[5].queryu(x[2][i]))  %mod;
    }
    for(int i=1;i<=n;i++){
        ans=(ans+1ll*num[x[3][i]]*T[1].queryu(x[3][i]+1)%mod*T[2].queryu(x[3][i]+1)%mod*T[4].queryd(x[3][i]-1)%mod*T[5].queryd(x[3][i]-1))%mod;
        ans=(ans+1ll*num[x[3][i]]*T[1].queryu(x[3][i]+1)%mod*T[2].queryd(x[3][i])  %mod*T[4].queryu(x[3][i])  %mod*T[5].queryd(x[3][i]-1))%mod;
        ans=(ans+1ll*num[x[3][i]]*T[1].queryu(x[3][i]+1)%mod*T[2].queryd(x[3][i])  %mod*T[4].queryd(x[3][i]-1)%mod*T[5].queryu(x[3][i]))  %mod;
        ans=(ans+1ll*num[x[3][i]]*T[1].queryd(x[3][i])  %mod*T[2].queryu(x[3][i]+1)%mod*T[4].queryu(x[3][i])  %mod*T[5].queryd(x[3][i]-1))%mod;
        ans=(ans+1ll*num[x[3][i]]*T[1].queryd(x[3][i])  %mod*T[2].queryu(x[3][i]+1)%mod*T[4].queryd(x[3][i]-1)%mod*T[5].queryu(x[3][i]))  %mod;
        ans=(ans+1ll*num[x[3][i]]*T[1].queryd(x[3][i])  %mod*T[2].queryd(x[3][i])  %mod*T[4].queryu(x[3][i])  %mod*T[5].queryu(x[3][i]))  %mod;
    }
    for(int i=1;i<=n;i++){
        ans=(ans+1ll*num[x[4][i]]*T[1].queryu(x[4][i]+1)%mod*T[2].queryu(x[4][i]+1)%mod*T[3].queryd(x[4][i])  %mod*T[5].queryd(x[4][i]-1))%mod;
        ans=(ans+1ll*num[x[4][i]]*T[1].queryu(x[4][i]+1)%mod*T[2].queryd(x[4][i])  %mod*T[3].queryu(x[4][i]+1)%mod*T[5].queryd(x[4][i]-1))%mod;
        ans=(ans+1ll*num[x[4][i]]*T[1].queryu(x[4][i]+1)%mod*T[2].queryd(x[4][i])  %mod*T[3].queryd(x[4][i])  %mod*T[5].queryu(x[4][i]))  %mod;
        ans=(ans+1ll*num[x[4][i]]*T[1].queryd(x[4][i])  %mod*T[2].queryu(x[4][i]+1)%mod*T[3].queryu(x[4][i]+1)%mod*T[5].queryd(x[4][i]-1))%mod;
        ans=(ans+1ll*num[x[4][i]]*T[1].queryd(x[4][i])  %mod*T[2].queryu(x[4][i]+1)%mod*T[3].queryd(x[4][i])  %mod*T[5].queryu(x[4][i]))  %mod;
        ans=(ans+1ll*num[x[4][i]]*T[1].queryd(x[4][i])  %mod*T[2].queryd(x[4][i])  %mod*T[3].queryu(x[4][i]+1)%mod*T[5].queryu(x[4][i]))  %mod;
    }
    for(int i=1;i<=n;i++){
        ans=(ans+1ll*num[x[5][i]]*T[1].queryu(x[5][i]+1)%mod*T[2].queryu(x[5][i]+1)%mod*T[3].queryd(x[5][i])  %mod*T[4].queryd(x[5][i]))  %mod;
        ans=(ans+1ll*num[x[5][i]]*T[1].queryu(x[5][i]+1)%mod*T[2].queryd(x[5][i])  %mod*T[3].queryu(x[5][i]+1)%mod*T[4].queryd(x[5][i]))  %mod;
        ans=(ans+1ll*num[x[5][i]]*T[1].queryu(x[5][i]+1)%mod*T[2].queryd(x[5][i])  %mod*T[3].queryd(x[5][i])  %mod*T[4].queryu(x[5][i]+1))%mod;
        ans=(ans+1ll*num[x[5][i]]*T[1].queryd(x[5][i])  %mod*T[2].queryu(x[5][i]+1)%mod*T[3].queryu(x[5][i]+1)%mod*T[4].queryd(x[5][i]))  %mod;
        ans=(ans+1ll*num[x[5][i]]*T[1].queryd(x[5][i])  %mod*T[2].queryu(x[5][i]+1)%mod*T[3].queryd(x[5][i])  %mod*T[4].queryu(x[5][i]+1))%mod;
        ans=(ans+1ll*num[x[5][i]]*T[1].queryd(x[5][i])  %mod*T[2].queryd(x[5][i])  %mod*T[3].queryu(x[5][i]+1)%mod*T[4].queryu(x[5][i]+1))%mod;
    }
    printf("%lld\n",ans);
    return 0;
}

T2

观察发现,只要有超过2的环那么一定有趣,因为单环显然,环上有东西路径的数量会变化

单自环没用,但是路劲上有两个自环也会构成有趣图,所以需要单独处理

跑个拓扑处理环和自环数量即可

#include<bits/stdc++.h>
#define N 500005
using namespace std;
int x[N],dis[N],sum[N],head[N],to[N],nxt[N],cnt=0,n,m;
queue<int>q;
void add(int u,int v){
    nxt[++cnt]=head[u];
    head[u]=cnt;
    to[cnt]=v;
    return;
}
void topo(){
    for(int i=1;i<=n;i++)if(!x[i])q.push(i);
    while(!q.empty()){
        int u=q.front();
        q.pop();
        dis[u]+=sum[u];
        for(int i=head[u];i;i=nxt[i]){
            x[to[i]]--;
            dis[to[i]]=max(dis[to[i]],dis[u]);
            if(!x[to[i]])q.push(to[i]);
        }
    }
    return;
}
signed main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
        int u,v;
        scanf("%d%d",&u,&v);
        if(u!=v){
            add(u,v);
            x[v]++;
        }
        else sum[u]++;
    }
    topo();
    for(int i=1;i<=n;i++)if(x[i]||dis[i]>1){
        printf("Yes\n");
        return 0;
    }
    printf("No\n");
    return 0;
}

T3

注意到如果能够把所有堆两两配对使得它们数量相同,那么后手每次在配对的另一堆上做先手做的事情就可以保证先手必败,否则先手一定能够在一步之后构成所有堆两两配对的局面使得先手必胜

#include<bits/stdc++.h>
#define int long long
#define N 200005
using namespace std;
int x[N];
signed main(){
    int T;
    scanf("%lld",&T);
    while(T--){
        int n;
        scanf("%lld",&n);
        for(int i=1;i<=n;i++)scanf("%lld",&x[i]);
        sort(x+1,x+n+1);
        if(n&1){
            int summ=0;
            for(int i=1;i<n;i+=2)summ+=x[i+1]-x[i];
            if(summ<x[n])printf("Yes\n");
            else printf("No\n");
        }
        else{
            int summ=0;
            for(int i=2;i<n;i+=2)summ+=x[i+1]-x[i];
            if(summ<x[n]-x[1])printf("Yes\n");
            else printf("No\n");
        }
    }
    return 0;
}
posted @ 2025-08-29 11:36  Igunareo  阅读(7)  评论(0)    收藏  举报