首页 > 其他分享 >中传校赛:小红的独特区间

中传校赛:小红的独特区间

时间:2024-03-21 23:02:09浏览次数:24  
标签:中传 int sum 小红 数字 区间 校赛 ll op

原题链接:G-小红的独特区间

题目大意:给定长度为n的数组,要求求出合法子数组方案数,合法的方案定义是:连续子数组恰好包含三种不同的数字。

思路:先将相同的数字缩成同一个数字,然后对于每一个数字,求出满足合法的区间的长度再计算总和即可。

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define endl '\n' 
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<ll,ll> pii;
const int N=1e6+10,mod=1e9+7;
ld pi=acos(-1.0);
ll p[N],pre[N];
struct node
{
	ll x,sum;
}q[N];
pii op[N];//记录正好为3的区间 
int main()
{
    ios::sync_with_stdio(NULL);cin.tie(0),cout.tie(0);
    ll n;cin>>n;
    for(int i=1;i<=n;i++)cin>>p[i];//正常读入 
    ll cnt=0;
    for(int i=1;i<=n;i++)//将连续相同的数字 缩成同一个点,并且用sum来记录数字个数 
    {
    	if(p[i]==p[i-1])
    	{
    		q[cnt].sum++;
		}
		else
		{
			cnt++;
			q[cnt].x=p[i];
			q[cnt].sum=1;
		}
	}
	ll sum=0;//代表当前枚举的区间几个不同的数据 
	for(int i=1;i<=cnt;i++)pre[i]=pre[i-1]+q[i].sum;//确定sum等于3的左右区间之后用前缀和来求可以优化复杂度 
	op[0]={0,0};op[cnt+1]=op[0];
	map<ll,ll> st;//记录当前区间的数字 
	for(int i=1,j=0;i<=cnt;i++)
	{
		ll l=0,r=0;
		st[q[i-1].x]-=q[i-1].sum;//减去前一个数的影响 
		if(!st[q[i-1].x]&&i>1)sum--;//如果减去前一个之后,st中就没有了前一个数,并且不能是q[0]这个没有意义的,那么代表需要减少一个数 
		if(sum==3)//如果正好为3,就代表从i到op[i-1].second的区间有三个不同的数字 
		{//用l和r代表op记录的区间,那么就是从i到l-1有2个不同的数字,从i到r有三个不同的数字 
		// 因为sum=3,那么r是确定的,但是l是不确定的,那么就从i往后面枚举,因为前面进行了缩点的操作,所以确定l的位置是非常快的 
			map<ll,bool> ui;
			ll jk=i;
			for(;jk<=cnt;jk++)
			{
				ui[q[jk].x]=1;
				if(ui.size()==3)break;
			}
			op[i]={jk,op[i-1].second};//记录 
			continue;
		}
		while(sum<=3&&j<=cnt)//如果小于3 
		{
			j++;
			if(!st[q[j].x])sum++;//如果当前点还没有记录,那么不同的数+1 
			st[q[j].x]+=q[j].sum;//每加入一个数就要加入这个点里面的数量 
			if(sum==3)
			{
				if(!l)l=j;
				r=j;
			}
		}
		st[q[j].x]-=q[j].sum;//j的位置是不合法的要去除 
		sum--;//如果是因为sum=4,退出循环那么就要减去j这个值的影响,如果j>cnt,0也是新的数字所以也要减去 
		if(j>cnt)
		{
			if(sum==3)op[i]={l,r};//到了最后一位,那么就要判断一下是从sum=2的状态到最后一位,还是从sum=3的状态到最后一位 
			else op[i]={0,0};
		}
		else
		{
			op[i]={l,r};//都没到最后就退出,那么一定是满足op的要求的 
		}
		j--;
	}
	ll ans=0;
	for(int i=1;i<=cnt;i++)
	{
		ll a=q[i].sum,l=op[i].first,r=op[i].second;//因为是连续的子数组并且只能三种数,那么影响方案的就是第一个数的数目和sum=3的范围 
		ll b=pre[r]-pre[l-1];//前缀和快速求 
		ans=ans+a*b;
	}
	cout<<ans<<endl;
	return 0;
}

标签:中传,int,sum,小红,数字,区间,校赛,ll,op
From: https://blog.csdn.net/qq_74190237/article/details/136891165

相关文章

  • 西理工校赛:PP 学姐的最短时间
    原题链接:K-PP学姐的最短时间​​​​​​题目大意:给n个点和m条边,给每条边通过的时间为a+b/(t+1),t为从当前点出发的时间。求从第一点到第n个点的最短时间。思路:这题明显是求最短路的题目,那么肯定可以使用迪杰斯特拉来跑最短路,但是二个点之间通过时间是动态的,那么如何来确定......
  • 2024年天梯成信校赛补题
    1-1代码胜于雄辩嘿嘿 L1-2收水费思路:分类讨论 L1-3日期思路:模拟 L1-4回文数思路:翻转后判断是否相等 L1-5yihan的新函数思路:模拟 L1-6二进制思路:二进制每位最多进位1,模拟下二进制加法即可 L1-7大山中的学院思路:统计每个山脉对空地的贡献 L1-8堆积木思......
  • 在sort中传入仿函数
    仿函数就是用来控制排列顺序的map<int,int,Compare>是这样,list.sort()也是这样.//List双向链表.cpp:此文件包含"main"函数。程序执行将在此处开始并结束。//#include<iostream>#include<list>usingnamespacestd;structCompare{ booloperator()(constint&......
  • 2024年天梯成信校赛
    2024年天梯成信校赛L1-1代码胜于雄辩-2024年天梯成信校赛补题(pintia.cn)就用PHPNoPHPcanbeusedinthiscontestsL1-2收水费-2024年天梯成信校赛补题(pintia.cn)#include<bits/stdc++.h>#definedebug(a)cout<<#a<<"="<<a<<'\n';using......
  • 小红书爬虫秘籍:轻松获取时尚穿搭灵感
    大家好!今天我来分享一下如何使用Python爬虫来获取小红书上的时尚穿搭灵感。小红书作为国内最大的时尚生活社区之一,拥有众多的时尚达人和潮流穿搭内容,如果你想获取最新的时尚灵感,就不容错过这个简单又有效的爬虫方法。在本文中,我将带领大家使用Python的Selenium和BeautifulSoup......
  • Node.js毕业设计仿小红书app(Express)
    本系统(程序+源码)带文档lw万字以上  文末可获取本课题的源码和程序系统程序文件列表系统的选题背景和意义选题背景:随着互联网技术的迅猛发展,社交媒体应用已成为人们日常生活中不可或缺的一部分。小红书作为一款集社区分享、电商购物于一体的综合性平台,以其独特的内容推荐......
  • Python实战:爬取小红书
    有读者在公众号后台询问爬取小红书,今天他来了。本文可以根据关键词,在小红书搜索相关笔记,并保存为excel表格。爬取的字段包括笔记标题、作者、笔记链接、作者主页地址、作者头像、点赞量。一、先看效果1、爬取搜索页2、爬取结果保存到本地excel表格运行我写的爬虫,......
  • [牛客]小红的数组分配
    题目思路去考虑sort排序为相同数字为偶数个,输出格式错误的去思考了数组为pair代码#include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;constintN=1e6+10;inti,j,k,n,m,t,res,a[N]={0};strings;voidslove(){ cin>>n; for(i=0;i<n*2;i++)ci......
  • [牛客]小红的正整数
    题目思路我的思路:排好序后找到几个0,在将最后一个0的右边一位输出,再根据0的个数输出0,再输出其余数字别人思路:排好序后将0右边一个和第一个0交换后,直接输出代码#include<bits/stdc++.h>usingnamespacestd;intmain(){chara[6]={};cin>>a;......
  • 《牛客》-D小红数组操作 (链表)
    思路:采用链表进行动态维护即可我们采用map集合来模拟链表结构(用结构体也是可以的)就是输出需要一点点思考.ACcode:#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongmap<int,int>l,r;intq,x,y,op,k;voidsolve(){ cin>>q; while(q--){ cin>>o......