当前位置: 首页 > news >正文

P8313 [COCI 2021/2022 #4] Izbori

洛谷

首先观察部分分,对于前两组部分分,可以直接暴力枚举左右端点。

对于第三组部分分,从前缀和的角度去思考,然后可以发现假设一个数字为正数,一个数字为负数,开桶进行统计,只要两种人数不打平即可。

代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,a[200005],tmp[200005],cnt,t[400005],ans;
void solve(){int tmp=0;for(int i=1;i<=n;i++){t[tmp+n+1]++;if(a[i]==2)tmp++;else tmp--;ans+=i-t[tmp+n+1];}cout<<ans;
}
signed main(){cin>>n;for(int i=1;i<=n;i++)scanf("%lld",&a[i]);for(int i=1;i<=n;i++)tmp[i]=a[i];sort(tmp+1,tmp+n+1);cnt=unique(tmp+1,tmp+n+1)-tmp-1;for(int i=1;i<=n;i++)a[i]=lower_bound(tmp+1,tmp+cnt+1,a[i])-tmp;if(cnt<=2){solve();return 0;}for(int i=1;i<=n;i++){for(int j=1;j<=cnt;j++)t[j]=0;int ma=0;for(int j=i;j<=n;j++){t[a[j]]++;ma=max(ma,t[a[j]]);if(ma>(j-i+1)/2)ans++;}}cout<<ans;return 0;
}

考虑怎么解决最后的问题。

观察前面的部分分做法,我们会很想枚举所有的种类进行处理,但是这样的种类实在是太多了。

我们可以考虑使用分治。

我们利用分治来解决,但是这样枚举的数字数量依然很大,但是我们还可以发现,实际上有效的数字并不多。

由于左端点位置确定在右边,左端点位置确定在左边部分,所以我们可以想到对于每一个有效点,仅在此点到中点时还满足条件,那么这个点可行。

可行的点有多少个?实际上最多只有 \(\log(n)\) 个,因为每个点要到达中点最少需要数量达到总数量一半以上,最后相当于多个二的幂次相加。

那么我们只需要在分治中预处理,预处理完以后再用前缀和进行统计即可。

代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,a[200005],ans,tmp[200005],cnt,t[200005],vis[200005],pre[400005];
vector<int> v;
void solve2(int x,int l,int r){int mid=l+r>>1;int tmp=n+1,mi=n+1,ma=n+1;pre[n+1]=1;for(int i=l;i<=mid-1;i++){if(a[i]==x)tmp++;else tmp--;pre[tmp]++;mi=min(mi,tmp),ma=max(ma,tmp);}if(a[mid]==x)tmp++;else tmp--;for(int i=mi+1;i<=ma;i++)pre[i]+=pre[i-1];for(int i=mid+1;i<=r;i++){if(a[i]==x)tmp++;else tmp--;if(tmp>ma)ans+=pre[ma];else if(tmp>=mi)ans+=pre[tmp-1];}for(int i=mi;i<=ma;i++)pre[i]=0;}
void solve(int l,int r){if(l==r)return void(ans++);int mid=l+r>>1;solve(l,mid),solve(mid+1,r);for(int i=l;i<=mid;i++){t[a[i]]++;if(t[a[i]]*2>mid-i+1&&!vis[a[i]])v.push_back(a[i]),vis[a[i]]=1;}for(int i=l;i<=mid;i++)t[a[i]]=0;for(int i=mid+1;i<=r;i++){t[a[i]]++;if(t[a[i]]*2>i-mid&&!vis[a[i]])v.push_back(a[i]),vis[a[i]]=1;}for(int i=mid+1;i<=r;i++)t[a[i]]=0;for(int i=l;i<=r;i++)vis[a[i]]=0;for(int i:v)solve2(i,l,r);v.clear();
}
signed main(){cin>>n;for(int i=1;i<=n;i++)cin>>a[i];for(int i=1;i<=n;i++)tmp[i]=a[i];sort(tmp+1,tmp+n+1);cnt=unique(tmp+1,tmp+n+1)-tmp-1;for(int i=1;i<=n;i++)a[i]=lower_bound(tmp+1,tmp+cnt+1,a[i])-tmp;solve(1,n);cout<<ans;return 0;
}
http://www.gsyq.cn/news/75744.html

相关文章:

  • 2025 最新智能制造服务商 / 厂家 TOP5 评测!科技赋能 + 全周期服务权威推荐榜单发布,引领智慧工厂建设新生态
  • CF762E Radio stations
  • 【拓补排序 TB_sort】P4017 最大食物链计数
  • 2025年深圳AI搜索排名优化公司推荐
  • Easysearch 2.0.0 性能测试
  • 基于STM32标准库的FreeRTOS移植与任务创建 - 详解
  • 2025 最新工业机器人应用服务商 / 厂家 TOP5 评测!科技赋能 + 全生命周期服务权威榜单发布,重构智能制造生态
  • Launch X431 PRO3 V+ Elite: Bi-Directional, ECU Coding Topology Mapping for Euro/Amer Vehicles
  • linux单用户模式
  • 吉他自学笔记
  • 为全球宝宝选对营养:央视关注+进博亮相,德国安心之选inne
  • 2025 年 12 月法兰保护罩厂家权威推荐榜:阀门保温罩/法兰防溅罩/法兰保护套,专业防护与耐用品质深度解析
  • openEuler:构建AI原生操作系统的架构演进与实践路径
  • FFmpeg开发笔记(九十二)基于Kotlin的开源Android推流器StreamPack
  • Microsoft Visual Studio 2010 TFS强制解除签出
  • HTTP/2在EDI领域中的优势:构建高效、安全、现代化的数据交换基石 - 详解
  • why Picograph can not learn English by translator
  • cursor
  • openEuler 软件生态多元适配评测:分布式存储与大数据组件实战验证
  • 短视频矩阵架构搭建指南:源码部署与全流程解析
  • 完整教程:Docker学习笔记---day001
  • 2025年度靠谱的实验室反应釜厂家TOP5权威推荐
  • 基于Python+Vue开发的婚恋交友管理系统源码+运行步骤+计算机专业
  • Python线程指南
  • 【基础】Unity着色器编程的语言和数学基础介绍
  • 2025年评价高的Q235模具钢/模具钢45#锯切厂家最新权威推荐排行榜
  • 显微镜品牌哪家强?2025年最新市场格局分析与五大高价值品牌推荐
  • 2025年重庆梁山鸡品牌排行榜,解析重庆李子坝梁山鸡适合朋友
  • 凸优化理论(五)-勒让德变换
  • 显微镜品牌哪家强?2025年最新市场分析与五大高价值品牌推荐