预祝2025省选嗨翻天

预祝2025省选嗨翻天

T1 A. 单峰序列 8pts

  • 部分分

    点击查看代码
    int a[500010],b[500010],c[500010],ans[500010],id;
    vector<int>l,r;
    struct BIT
    {
        int c[500010];
        int lowbit(int x)
        {
            return (x&(-x));
        }
        void add(int n,int x,int val)
        {
            for(int i=x;i<=n;i+=lowbit(i))  c[i]+=val;
        }
        int getsum(int x)
        {
            int ans=0;
            for(int i=x;i>=1;i-=lowbit(i))  ans+=c[i];
            return ans;
        }
    }T;
    void dfs(int pos,int n)
    {
        if(pos==n+1)
        {
            b[0]=0;
            for(int i=0;i<l.size();i++)
            {
                b[0]++;  b[b[0]]=l[i];
            }
            sort(b+1,b+1+b[0]);
            b[0]++;  b[b[0]]=a[id];
            int tmp=b[0]+1;
            for(int i=0;i<r.size();i++)
            {
                b[0]++;  b[b[0]]=r[i];
            }
            sort(b+tmp,b+1+b[0],greater<int>());
            for(int i=1;i<=n;i++)  c[b[i]]=i;
            for(int i=1;i<=n;i++)  
            tmp=0;
            for(int i=n;i>=1;i--)
            {
                tmp+=T.getsum(c[a[i]]-1);  T.add(n,c[a[i]],1);
            }
            ans[n]=min(ans[n],tmp);
            for(int i=1;i<=n;i++)  T.add(n,c[a[i]],-1);
        }
        else
        {
            if(pos==id)  dfs(pos+1,n);
            else
            {
                l.push_back(a[pos]);  dfs(pos+1,n);  l.pop_back();
                r.push_back(a[pos]);  dfs(pos+1,n);  r.pop_back();
            }
        }
    }
    int main()
    {
    #define Isaac
    #ifdef Isaac
        freopen("seq.in","r",stdin);
        freopen("seq.out","w",stdout);
    #endif
        int n,t,i;
        cin>>n>>t;
        memset(ans,0x3f,sizeof(ans));
        for(i=1;i<=n;i++)
        {
            cin>>a[i];
            if(a[i]>a[id])  id=i;
            dfs(1,i);
        }
        if(t==1)  for(i=1;i<=n;i++)  cout<<ans[i]<<endl;
        else  cout<<ans[n]<<endl;
        return 0;
    }
    
  • 正解

    • 考虑 ax 在最终单峰序列中位于 ak 前还是 ak 后,两者产生的逆序对/交换次数分别为 i=1x1[ai>ax],i=x+1r[ai>ax] ,不妨设两个值分别为 px,qx,r 。贪心地取 min(px,qx,r) 作为其贡献即可。
    • 观察到 qx,r 随着 r 单调不降,考虑二分找到其分界点 limitx 使得 limitx 以前 pxqx,rlimitx 以后 px<qx,r
    • 动态维护 qx,r 的变化,此时是一个矩阵加、单点查询的形式,扫描线即可。
    点击查看代码
    ll a[500010],pos[500010],sum[500010];
    vector<ll>c[500010];
    struct BIT
    {
        ll c[500010];
        ll lowbit(ll x)
        {
            return (x&(-x));
        }
        void clear()
        {
            memset(c,0,sizeof(c));
        }
        void add(ll n,ll x,ll val)
        {
            for(ll i=x;i<=n;i+=lowbit(i))  c[i]+=val;
        }
        void update(ll n,ll l,ll r,ll val)
        {
            add(n,l,val);  add(n,r+1,-val);
        }
        ll getsum(ll x)
        {
            ll ans=0;
            for(ll i=x;i>=1;i-=lowbit(i))  ans+=c[i];
            return ans;
        }
    }B[2];
    int main()
    {
    #define Isaac
    #ifdef Isaac
        freopen("seq.in","r",stdin);
        freopen("seq.out","w",stdout);
    #endif
        ll n,t,ans,l,r,mid,i,j;
        scanf("%lld%lld",&n,&t);
        for(i=1;i<=n;i++)
        {
            scanf("%lld",&a[i]);  pos[a[i]]=i;
            B[0].add(n,a[i],1);
            sum[i]=i-B[0].getsum(a[i]);
        }
        B[0].clear();
        for(i=n;i>=1;i--)
        {
            l=pos[i];  r=n;  ans=0;
            while(l<=r)
            {
                mid=(l+r)/2;
                if(B[0].getsum(mid)-B[0].getsum(pos[i])<=sum[pos[i]])
                {
                    ans=mid;
                    l=mid+1;
                }
                else  r=mid-1;
            }
            c[ans+1].push_back(a[pos[i]]);
            B[0].add(n,pos[i],1);
        }
        ans=0;
        for(i=1;i<=n;i++)
        {
            if(a[i]+1<=n)  B[1].update(n,a[i]+1,n,1);
            for(j=0;j<c[i].size();j++)  B[1].update(n,c[i][j],n,-1);
            ans+=B[1].getsum(a[i]);
            if(i==n||t==1)  printf("%lld\n",ans);
        }
        return 0;
    }
    
    

T2 B. 划分线段 10pts

T3 C. 红蓝树 20pts

  • 部分分

    • 20pts :模拟。
    点击查看代码
    int a[600010];
    stack<int>s;
    int main()
    {
    #define Isaac
    #ifdef Isaac
        freopen("rbtree.in","r",stdin);
        freopen("rbtree.out","w",stdout);
    #endif
        int n,m,pd,l,r,ans=0,col,i,j;
        scanf("%d%d",&n,&m);
        for(i=1;i<=n;i++)  
        {
            scanf("%d",&a[i]);  a[i]--;
        }
        for(j=1;j<=m;j++)
        {
            scanf("%d%d%d",&pd,&l,&r);
            if(pd==1)  for(i=l;i<=r;i++)  a[i]^=1;
            else
            {
                ans=col=0;
                while(s.empty()==0)  s.pop();
                for(i=l;i<=r;i++)
                {
                    if(a[i]<=1)
                    {
                        ans+=(a[i]||col);  s.push((a[i]||col));
                        col=0;
                    }
                    else  if(s.empty()==0)
                    {
                        col|=s.top();
                        s.pop();
                    }
                }
                printf("%d\n",ans);
            }
        }
        return 0;
    }
    
  • 正解

总结

  • 罚坐。
posted @   hzoi_Shadow  阅读(32)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
扩大
缩小
点击右上角即可分享
微信分享提示