首页 > 其他分享 >P10833 [COTS 2023] 下 Niz

P10833 [COTS 2023] 下 Niz

时间:2024-11-06 19:43:50浏览次数:1  
标签:node lg return P10833 int 最大值 st Niz 2023

题目链接

主要算法

分治(最大值分治),st表

思路

1.因为我们考虑最主要的限制条件是最大值和排列,所以如果我们知道最大值就知道答案的长度。所以考虑按最大值分治,统计左边对右边的贡献。
2.接下来就是如何快速考虑一个区间是否合法,一个显然的是没有相同数,所以可以记前一个数的位置的最大值,如果小于左端点就符合条件。同时我们发现这样还恰好满足了每个数都出现的要求(因为固定了最大值,所以只能出现1-max)。
3.所以用两个st表记最大值即可

#include  <bits/stdc++.h>
using namespace std;
const int N=2e6+10;
#define ll long long
int n,g[N][21],las[N],lg[N];//不要压线开
struct node
{
	int fi,se;
}f[N][21];//同时存位置和最大值
ll ans;
node maxx(node x,node y)
{
	return x.fi>=y.fi?x:y;
}
node query1(int l,int r)
{
    int cd=lg[r-l+1];
    return maxx(f[l][cd],f[r-(1<<cd)+1][cd]);
}
int query2(int l,int r)
{
    int cd=lg[r-l+1];
    return max(g[l][cd],g[r-(1<<cd)+1][cd]);
}
void solve(int l,int r)
{
    if(l>r)return ; 
    int mx=query1(l,r).fi,mxz=query1(l,r).se,mid=n+1;//必须直接找到中点,保证时间复杂度 
    if(mxz-l<=r-mxz)//选小的才能保证时间复杂度
    for(int i=max(mxz-mx+1,l);i<=mxz;i++)
    {  
        int j=i+mx-1;
        if(j>r)break;
        if(query2(i,j)<i)ans++;
    }
    else
    for(int j=mxz;j<=min(mxz+mx-1,r);j++)
    {  
        int i=j-mx+1;
        if(i<l)continue;
        if(query2(i,j)<i)ans++;
    }
    solve(l,mxz-1);
    solve(mxz+1,r);
    return ;
}
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        int x;cin>>x;
        f[i][0]=(node){x,i};
        g[i][0]=las[x];
        las[x]=i;
    }
    lg[0]=-1;
    for(int i=1;i<=n;i++)lg[i]=lg[i/2]+1;
    for(int j=1;j<=lg[n];j++)
        for(int i=1;i+(1<<j)-1<=n;i++)
	  		f[i][j]=maxx(f[i][j-1],f[i+(1<<(j-1))][j-1]),g[i][j]=max(g[i][j-1],g[i+(1<<(j-1))][j-1]);
    solve(1,n);
	cout<<ans<<'\n';
    return 0;
}

相同思路的题:P4755 Beautiful Pair

最大值分治+主席树秒了!

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
#define ll long long
int n,cnt,st[N][18],a[N],ls[31*N],rs[31*N],rt[N],lg[N],mx;
ll ans,sh[31*N];
int query(int x,int l,int r,int k)
{
	if(l>k||l>r||!x)return 0;
	if(r<=k&&l>=1)return sh[x];
	int mid=(l+r)>>1;
	ll sum=0;
	sum+=query(ls[x],l,mid,k);
	sum+=query(rs[x],mid+1,r,k);
	return sum; 
}
int querymax(int l,int r)
{
	int cd=lg[r-l+1];
	return a[st[l][cd]]>=a[st[r-(1<<cd)+1][cd]]?st[l][cd]:st[r-(1<<cd)+1][cd]; 
}
void solve(int l,int r)
{
	if(l>r)return ;
	int wz=querymax(l,r);
//	cout<<l<<" "<<r<<" "<<wz<<'\n'; 
	if(wz-l<r-wz)
	{
		for(int i=l;i<=wz;i++)
		{
			int ned=a[wz]/a[i];
			ans+=query(rt[r],1,mx,ned)-query(rt[wz-1],1,mx,ned);
		}
	} 
	else
	{
		for(int i=wz;i<=r;i++)
		{
			int ned=a[wz]/a[i];
			ans+=query(rt[wz],1,mx,ned)-query(rt[l-1],1,mx,ned);
		}
	}
	solve(l,wz-1);solve(wz+1,r);
}
void modify(int oldx,int &newx,int l,int r,int wz)
{
	newx=++cnt;ls[newx]=ls[oldx],rs[newx]=rs[oldx];
	if(l==r)
	{
		sh[newx]=sh[oldx]+1;
		return ;
	}
	int mid=(l+r)>>1;
	if(wz<=mid)modify(ls[oldx],ls[newx],l,mid,wz);
	else modify(rs[oldx],rs[newx],mid+1,r,wz);
	sh[newx]=sh[ls[newx]]+sh[rs[newx]];
	return ;
}
int main()
{
	cin>>n;
	lg[0]=-1;
	for(int i=1;i<=n;i++){cin>>a[i];mx=max(a[i],mx);}
	for(int i=1;i<=n;i++)
	{
		st[i][0]=i;
		modify(rt[i-1],rt[i],1,mx,a[i]);
		lg[i]=lg[i/2]+1;
	} 
	for(int j=1;j<=lg[n];j++)
		for(int i=1;i+(1<<j)-1<=n;i++)
			st[i][j]=a[st[i][j-1]]>=a[st[i+(1<<(j-1))][j-1]]?st[i][j-1]:st[i+(1<<(j-1))][j-1];
	solve(1,n);
	cout<<ans<<'\n';
	return 0;
}

标签:node,lg,return,P10833,int,最大值,st,Niz,2023
From: https://www.cnblogs.com/storms11/p/18530907

相关文章

  • 【Tableau2023软件下载与安装教程】
    Tableau2023‌是一款强大的数据可视化和数据分析软件,广泛应用于商业智能领域。它通过提供直观的界面和丰富的数据分析功能,使用户能够轻松地从复杂的数据中提取见解和策略,从而加速数据分析和报告生成的过程‌。1、安装包  Tableau2023:链接:https://pan.quark.cn/s/195fd628......
  • CCPC Final 2023 B. Periodic Sequence
    https://vjudge.net/problem/QOJ-8543给定\(n\),对于\(i=1,2,\ldots,n\)求出最长可能的周期字符串序列长度F(i),满足序列中字符串的长度\(≤i\)。一个字符串序列\(S_1,S_2,\ldots,S_l\)是周期字符串序列,当且仅当对于每个\(1≤i<l\)都满足\(S_i\)是\(S_{i+1}\)的周期......
  • Synchronized用过吗,其原理是什么
    synchronized是由一对monitorenter/monitorexit指令实现的,monitor对象是同步的基本实现单元。在Java6之前,monitor的实现完全是依靠操作系统内部的互斥锁,因为需要进行用户态到内核态的切换,所以同步操作是一个无差别的重量级操作,性能也很低。但在Java6的时候,Java虚拟机......
  • Synchronized用过吗,其原理是什么
    synchronized是由一对monitorenter/monitorexit指令实现的,monitor对象是同步的基本实现单元。在Java6之前,monitor的实现完全是依靠操作系统内部的互斥锁,因为需要进行用户态到内核态的切换,所以同步操作是一个无差别的重量级操作,性能也很低。但在Java6的时候,Java虚拟机......
  • 关于idea连接数据库时报错:Cannot run program E:\IntelliJ_IDEA_2023.3.4\jbr\bin
    问题说明连接mysql数据库时在点击testconnection时弹出的问题:CannotrunprogramE:\IntelliJ_IDEA_2023.3.4\jbr\bin\javacreateprocesserror=5,拒绝访问查询多个网站都没有找到解决方案。解决方法点击左侧Drivers,找到MySQL右侧点击Advanced在最下方的VMhome......
  • synchronized的monitor监视器
    publicclassT{@SneakyThrowspublicstaticvoidmain(String[]args){System.out.println("此行后加锁monitorenter");synchronized(T.class){System.out.println("hellomonitor");}Syste......
  • Java多线程编程(三)一>详解synchronized, 死锁,wait和notify
    目录: 一.synchronized的使用:   二. 常见死锁情况: 三.如何避免死锁:  四.wait和notify一.synchronized的使用: 我们知道synchronized锁具有互斥的特点:synchronized会起到互斥效果,某个线程执行到某个对象的synchronized中时,其他线程如果也执......
  • Stack Overflow 2023 年开发者调查报告!
    StackOverflow发布了2023年开发者调查报告,据称共计超过9万名开发者参与了此次调查。完整报告包含了受访开发者画像,以及关于开发技术、AI、职业、社区等方面的内容。本文主要介绍关于开发技术和AI的部分。懒人目录:最流行编程语言:JavaScript最“赚钱”编程语言......
  • [PA2024] Modernizacja Bajtocji 题解
    DescriptionByteland正在走向现代化。最新的政府项目旨在为那些没有电脑的村镇居民提供电脑。Byteasar正在监督该计划中的一个村庄——Bytetown——的现代化进程,目前那里没有一个居民拥有电脑。Bytetown有\(n\)个居民,为了简单起见,Byteasar将他们用\(1\)到\(n\)的整数......
  • [2023四校联考3]flandre
    flandre题目:芙兰朵露有nn种烟花,每种都有两个参数:「真实效果」aa和「感觉效果」bb,其中「真实效果」是一个给定不变的整数(可以为负),「感觉效果」初值等于「真实效果」。将烟花按一定顺序燃放,先燃放的烟花会使得后面「真实效果」较差的烟花「感觉效果」更差,「真实效果」更优的「......