2022春每日一题:Day 36
题目:[JLOI2013]删除物品
直接做显然比较复杂,这个题是说对顶栈,但是可以把两个栈拼在一起,记录一下栈顶的下标,然后这样这题就可以转化为线性上的操作查询了,用树状数组简单维护一下就ok了(某个数是否存在,单点修改+区间查询)
代码:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#define lowbit(x) x&-x
const int N=1e5+5;
using namespace std;
int n1,n2,a[N],b[N],c[N],n,dy[N];
struct pos
{
int id,v;
pos(int ii,int vv)
{
id=ii;v=vv;
}
pos(){
}
friend bool operator < (pos a,pos b)
{
return a.v<b.v;
}
}nums[N];
namespace fenwick
{
struct fw
{
int c;
}e[N];
void modify(int x,int v)
{
for(int i=x;i<=n;i+=lowbit(i))
e[i].c+=v;
}
int query(int x)
{
int ret=0;
for(int i=x;i;i-=lowbit(i))
ret+=e[i].c;
return ret;
}
}
using namespace fenwick;
int main()
{
scanf("%d %d",&n1,&n2);
for(int i=1;i<=n1;i++)
scanf("%d",&a[i]),c[n1-i+1]=a[i];
for(int i=1;i<=n2;i++)
scanf("%d",&b[i]),c[n1+i]=b[i];
n=n1+n2;
for(int i=1;i<=n;i++)
nums[i]=pos(i,c[i]);
sort(nums+1,nums+1+n);
int last=-1,cnt=1;
for(int i=1;i<=n;i++)
{
if(last!=nums[i].v)
last=nums[i].v,cnt=i;
dy[cnt]=nums[i].id;
}
for(int i=1;i<=n;i++)
modify(dy[i],1);
int now=n1;
long long ret=0;
for(int i=n;i;i--)
{
if(dy[i]<=now)
{
ret+=query(now)-query(dy[i]);
now=dy[i];
}
else
{
ret+=query(dy[i]-1)-query(now);
now=dy[i]-1;
}
modify(dy[i],-1);
}
printf("%lld\n",ret);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话