F.双生双宿之探
1.校门外的树(一维差分)2.铺地毯(二维差分/枚举区间)3.晾衣服(二分)4.丢手绢(尺取法/快慢指针)5.二分(离散化/哈希)6.C-猪猪养成计划1(set)7.E-双生双宿之错8.D-字符串里串9.H-一起画很大的圆10.C-字符串外串11.E—一起走很长的路12.M—数值膨胀之美13.J—硝基甲苯之袭14.H—井然有序之窗15.C—智乃的NotePad(esay version)16.I. 小鸡的排列构造的checker17.J. 铁刀磨成针18.华华开始学信息学19.B.好伙计猜拳20.E.小L的井字棋21.C.小L的位运算22.D.Tokitsukaze and Concatenate Palindrome23.C.Tokitsukaze and Balance String (hard)24.E.智乃的小球25.G.智乃与模数26.D.小L的字符串翻转27.L.小L的构造28.C.兢兢业业之移
29.F.双生双宿之探
30.E.全都要31.D.大预言家题目链接:https://ac.nowcoder.com/acm/contest/95323/F
题意:
给定一个长度为n的数组a,规定若其一个子数组 长度为偶数 并且数组内 有两个不相同的数字 且 数量相同 ,则该数组为双生数组
求数组a中有多少个双生数组
思路:
纯暴力枚举每一个区间显然复杂度O(nnn)
考虑到 从左往右扩展区间 若区间数字种类超过两个便停止 ,发现此区间的下一个区间,一定不会与拥有 此区间最左边的数字 的区间 相交,而只会最大程度上与 拥有 此区间最右边的数字 的区间 相交
那么一左一右 就可以用双指针 枚举代价变为O(n)
当确定了区间之后,就需要统计此区间双生数组的数目
如何统计?既然要让两种数字的数目相同,不妨离散化,让一种数字变为1,另一种数字变为-1。这样 若 子区间的区间和为0,说明子区间两种数字数目相同,就说明这是一个双生数组
如何确定子区间区间和?显然用前缀和解决,既然 presum[x]-presum[y-1]=0 证明[x,y]为一个双生数组 那么只要看presum[x]=presum[y-1]
用set保证两种数字,map存储从l~r的前缀和,额外复杂度为O(logn)
值得注意的是本来寻思着双指针复杂度是O(n),然后前缀遍历一遍复杂度看着也像O(n)那搞里头不应该变成O(nnlogn)级别的了吗》
后来想想发现双指针扩的区域越大,双指针遍历的就越少,前缀遍历的就越多;双指针扩的区域越小,双指针遍历的就越多,前缀遍历的就越少
所以两个乘起来是O(n)的~
#include<bits/stdc++.h>
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define pb push_back
#define int long long
#define endl "\n"
#pragma GCC optimize(3)
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int inf=0x3f3f3f3f;
const ll llmax=LLONG_MAX;
const int maxn=1e5+5;
const int mod=1e9+7;
int n;
int a[maxn];
void solve(){
cin>>n;
int ans=0;
rep(i,1,n) cin>>a[i];
for(int l=1;l<=n;){
map<int,int>mp;
set<int>st;
int r=l+1;
st.insert(a[l]);
while(st.size()<=2&&r<=n){
st.insert(a[r]);
if(st.size()==3){
st.erase(a[r]);r--;break;
}
r++;
}
if(r>n)r=n;
if(st.size()==1)break;
mp[0]=1;
int s=0;
rep(i,l,r){
s+=(a[i]==a[l]?1:-1);
ans+=mp[s];
mp[s]++;
// cout<<"s "<<s<<endl;
}
// rep(i,1,n){
// cout<<a[i]<<endl;
// }
// for(auto it:mp){
// cout<<it.first<<' '<<it.second<<endl;
// }
while(r-1>=l&&a[r-1]==a[r])r--;
l=r;
}
cout<<ans<<endl;
}
signed main()
{
ios::sync_with_stdio(false),cin.tie(0);
int T;cin>>T;
while(T--){
solve();
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人