首页 > 其他分享 >LibreOJ#535. 「LibreOJ Round #6」花火

LibreOJ#535. 「LibreOJ Round #6」花火

时间:2023-12-26 19:24:36浏览次数:27  
标签:stA LibreOJ int res mid 535 include Round

LibreOJ#535. 「LibreOJ Round #6」花火

\(n\) 个烟火排成一排,从左到右高度分别为 \(h_1,h_2,\cdots,h_n\),这些高度两两不同。
每次 Yoko 可以选择两个相邻的烟火交换,这样的交换可以进行任意多次。
每次 Yoko 还可以选择两个不相邻的烟火交换,但这样的交换至多进行一次。
你的任务是帮助 Yoko 用最少次数的交换,使这些烟火从左到右的高度递增。
对于所有数据,满足 \(1\le n\le 300,000\),\(1\le h_i\le n\),\(h_i\) 互不相同。

点击查看代码
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
#define int long long
#define N 300010
int n,a[N];
int topA,topB,stA[N],stB[N];
int Tree[N<<2],tag[N<<2],sum[N];
int cnt,flag[N];
struct Node
{
	int y,l,r,val;
	
	bool operator < (const Node &rhs) const
	{
		if (y==rhs.y) return val<rhs.val;
		return y<rhs.y;
	}
	
}buc[N<<1];

int read ()
{
	int k=1,s=0;char ch=getchar ();
	while (!isdigit (ch)) {if (ch=='-') k=-1;ch=getchar ();}
	while (isdigit (ch)) {s=s*10+ch-'0';ch=getchar ();}
	return k*s;
}

int FindA (int x)
{
	int L=1,R=topA,res=0;
	while (L<=R)
	{
		int mid=(L+R)>>1;
		if (a[stA[mid]]>a[x])
		{
			res=mid;
			R=mid-1;
		}
		else L=mid+1;
	}
	return stA[res];
}

int FindB (int x)
{
	int L=1,R=topB,res=0;
	while (L<=R)
	{
		int mid=(L+R)>>1;
		if (a[stB[mid]]<a[x])
		{
			res=mid;
			R=mid-1;
		}
		else L=mid+1;
	}
	return stB[res];
}

void Modify (int i,int l,int r,int x,int y,int val)
{
	if (x<=l && r<=y)
	{
		Tree[i]+=val,tag[i]+=val;
		return;
	}
	int mid=(l+r)>>1;
	if (x<=mid) Modify (i<<1,l,mid,x,y,val);
	if (mid<y) Modify (i<<1|1,mid+1,r,x,y,val);
	Tree[i]=max (Tree[i<<1],Tree[i<<1|1])+tag[i];
}

int lowbit (int x)
{
	return x&(-x); 
}

void Update (int x)
{
	while (x<=n)
	{
		sum[x]++;
		x+=lowbit (x);
	}
}

int Getsum (int x)
{
	int res=0;
	while (x>0)
	{
		res+=sum[x];
		x-=lowbit (x);
	}
	return res;
}

void Init ()
{
	n=read ();
	for (int i=1;i<=n;i++)
		a[i]=read ();
}

void Work ()
{
	for (int i=1;i<=n;i++)
		if (i==1 || a[i]>a[stA[topA]])
		{
			stA[++topA]=i;
			flag[i]=1;
		}
	for (int i=n;i>=1;i--)
		if (i==n || a[i]<a[stB[topB]])
		{
			stB[++topB]=i;
			flag[i]=1;
		}
	for (int i=1;i<=n;i++)
	{
		if (flag[i]) continue;
		int L=FindA (i),R=FindB (i);
		if (L<i && i<R)
		{
			buc[++cnt]=(Node) {i+1,L,i-1,1};
			buc[++cnt]=(Node) {R+1,L,i-1,-1};
		}
	}
	sort (buc+1,buc+1+cnt);
	int ans=0;
	for (int i=1;i<=cnt;i++)
	{
		Modify (1,1,n,buc[i].l,buc[i].r,buc[i].val);
		if (buc[i].y!=buc[i+1].y) ans=max (ans,Tree[1]);
	}
	ans=-2*ans;
	for (int i=n;i>=1;i--)
	{
		ans+=Getsum (a[i]-1);
		Update (a[i]);
	}
	printf ("%lld\n",ans);
}

signed main ()
{
	Init ();
	Work ();
}

标签:stA,LibreOJ,int,res,mid,535,include,Round
From: https://www.cnblogs.com/TomCat-WXY/p/17929123.html

相关文章

  • Codeforces Round 915 (div2) E
    E.TreeQueries[题目链接](https://codeforces.com/contest/1904/problem/EProblem-E-Codeforces)题意概括:给定一棵大小为\(n\)的树,回答如下询问,询问之间相互独立:给定一个点\(x\)与\(k\)个点\(a_i\),求出从\(x\)出发不经过任何一个\(a_i\)的最长简单路径长度......
  • P5350 序列
    题意维护一个序列:区间查询区间赋值区间加法区间复制区间交换区间翻转数据随机。Sol珂朵莉。前\(3\)个操作很\(trivial\)。考虑区间复制。先把两个区间\(split\)出来。然后扔进\(vector\),全部\(erase\)掉。再用\(vector\)\(insert\)进去。随便搞搞就过......
  • Codeforces Round 917 (Div. 2)
    基本情况A题秒了,B题卡了一年。B.EraseFirstorSecondLetterProblem-B-Codeforces卡题分析两方面原因没有变通,一开始的思路是公式算出总字串数再想办法找重复的减掉,但搞了一个小时都不可行,应该早点换成正着来找的思路。没有更深入的分析样例。最后虽然出来了,......
  • CF contest 1909 Pinely Round 3 (Div. 1 + Div. 2) 题解(Vanilla的掉分赛)
    CFcontest1909PinelyRound3(Div.1+Div.2)Vanilla的掉分赛绪言PinelyRound3(Div.1+Div.2)-Codeforces\[\color{purple}\large\textbf{世界上只有一种真正的英雄主义,}\]\[\color{red}\large\textbf{就是认清了生活的真相后还依然热爱它。}\]\[\color{gray}......
  • Pinely Round 3 (Div. 1 + Div. 2)
    A构造题,分两种情况考虑上下都行,左右选一个左右都行,上下选一个voidsolve(){ intn; cin>>n; vector<pair<int,int>>a(n); for(auto&t:a)cin>>t.x>>t.y; sort(a.begin(),a.end()); boolokx=a[0].x*a.back().x>=0; for(auto&am......
  • background-size: cover与background-size: contain
    background-size的可能值background-size的可能值是auto, contain,和cover.1、background-size:cover在这里,图像将被调整大小以适应容器。如果长宽比不一样,那么图像将被屏蔽以适应。当使用background-size:cover时,请确保考虑图像的长宽比。2、background-size:contain......
  • Codeforces Round 651 (Div. 2)C. Number Game(数学思维数论)
    C.NumberGame我们考虑那些状态是必胜态我的回合时n为奇数(除1外),直接除以n则必胜下面偶数的情况稍复杂偶数我们能进行的操作只有除以一个奇数,需要考虑怎么把当前状态变为对手的必败态偶数一定含2的因子,\(n=2^k*q,q为奇数\)当\(k=1时如果q\)是一个质数那么只能除一次q这样......
  • golang简单判断22-65535开发情况
    packagemainimport( "fmt" "net" "sync" "time")funcmain(){ server:="42.51.129.175"//要检查的服务器地址 ports:=make([]int,65535)//要检查的端口范围,从22到65535 fori:=22;i<=65535;i++{ ports......
  • Codeforces Round 916 (Div. 3)
    目录写在前面ABCDE1/E2FG1G2写在最后写在前面比赛地址:https://codeforces.com/contest/1914。第二天没早八打个div3休闲娱乐保持下手感,然而div3都AK不了了,纯纯废物一个,天天上大学导致的。唉,一学期碰上好几个byd恼弹老师,大学一秒也不想上了,折磨。马娘台服马上1.5周......
  • Educational Codeforces Round 160 (Rated for Div. 2)
    A.RatingIncrease字符串处理#include<bits/stdc++.h>usingnamespacestd;voidsolve(){ strings; cin>>s; intn=s.size(); s=""+s; for(inti=1;i<=n-1;i++){ stringt=""; for(intj=1;j<=i;j++){ t=t+s[j]; } ......