[CF1558D]Top-Notch Insertions

2024-03-16 22:48
文章标签 top notch cf1558d insertions

本文主要是介绍[CF1558D]Top-Notch Insertions,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Top-Notch Insertions

题解

首先,原操作相当于一种排序的方式,每次操作相当于告诉我们这个数比现在已经操作过且在它后面的数小,不小于它前面的数。
我们可以理解成加一个 < < < ⩽ \leqslant 的符号。
如果我们将 i i i插入到 a j − 1 a_{j-1} aj1 a j a_{j} aj之间,相当于将原来两者的关系变为 a j − 1 ⩽ i < a j a_{j-1}\leqslant i<a_{j} aj1i<aj
很容易发现,上面的操作我们可以用平衡树进行维护,注意 ∑ m ⩽ 2 × 1 0 5 \sum m\leqslant 2\times 10^5 m2×105 ∑ n \sum n n不保证范围,所以我们只能将它给出的操作插入到平衡树中。

既然我们可以统计出 < < <的的个数,那么我们也知道至少有多少个不同的数,我们可以枚举相同的连续 ⩽ \leqslant 段与总共的不同的数的个数。
但这样仍然会使得我们的复杂度中存在 O ( ∑ n ) O\left(\sum n\right) O(n)因为这样差不多是从 m m m n n n枚举了,如果我们要让它从 0 0 0 m m m的话就只能容斥了。
但实际上我们有一种更加简便的做法。
如果全都是 ⩽ \leqslant 的话我们的方案数是 ( 2 n n ) \binom{2n}{n} (n2n),相当于就是差分的形式,选择的点前面有多少个点没有选择,就是它的值。
如果加入 < < <我们可以看作每个 < < <自己绑定一个没选的空点,与上面一样,方案数为 ( 2 n − t n ) \binom{2n-t}{n} (n2nt) t t t表示有多少个 < < <

时间复杂度 O ( ∑ m l o g m ) O\left(\sum mlog\,m\right) O(mlogm)

源码

#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
#define MAXN 400005
#define lowbit(x) (x&-x)
#define reg register
#define pb push_back
#define mkpr make_pair
#define lson (rt<<1)
#define rson (rt<<1|1)
#define fir first
#define sec second
typedef long long LL;
typedef unsigned long long uLL;
const LL INF=0x3f3f3f3f3f3f;
const int mo=998244353;
const int inv2=499122177;
const int jzm=2333;
const int zero=10000;
const int lim=10000;
const int orG=3,invG=332748118;
const double Pi=acos(-1.0);
const double eps=1e-7;
typedef pair<int,int> pii;
template<typename _T>
_T Fabs(_T x){return x<0?-x:x;}
template<typename _T>
void read(_T &x){_T f=1;x=0;char s=getchar();while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}while('0'<=s&&s<='9'){x=(x<<3)+(x<<1)+(s^48);s=getchar();}x*=f;
}
template<typename _T>
void print(_T x){if(x<0){x=(~x)+1;putchar('-');}if(x>9)print(x/10);putchar(x%10+'0');}
LL gcd(LL a,LL b){return !b?a:gcd(b,a%b);}
int add(int x,int y,int p){return x+y<p?x+y:x+y-p;}
void Add(int &x,int y,int p){x=add(x,y,p);}
int qkpow(int a,int s,int p){int t=1;while(s){if(s&1LL)t=1ll*a*t%p;a=1ll*a*a%p;s>>=1LL;}return t;}
int n,m,p[MAXN];
int ans,fac[MAXN],inv[MAXN],f[MAXN];
void init(){fac[0]=fac[1]=inv[0]=inv[1]=f[1]=1;for(int i=2;i<=4e5;i++)fac[i]=1ll*i*fac[i-1]%mo,f[i]=1ll*(mo-mo/i)*f[mo%i]%mo,inv[i]=1ll*f[i]*inv[i-1]%mo;
}
int C(int x,int y){if(x<0||y<0||x<y)return 0;return 1ll*fac[x]*inv[y]%mo*inv[x-y]%mo;
}
struct ming{int siz,rnd,val,ch[2],sum,lzy,id;ming(){siz=rnd=val=sum=ch[0]=ch[1]=lzy=0;}
};
class FHQ_Treap{private:ming tr[MAXN];int tot,root;int newnode(int x,int y){int rt=++tot;tr[rt].siz=1;tr[rt].rnd=rand();tr[rt].ch[0]=tr[rt].ch[1]=tr[rt].lzy=0;tr[rt].val=tr[rt].sum=x;tr[rt].id=y;return rt; }void pushdown(int rt){if(tr[rt].lzy){if(tr[rt].ch[0])tr[tr[rt].ch[0]].lzy+=tr[rt].lzy,tr[tr[rt].ch[0]].id+=tr[rt].lzy;if(tr[rt].ch[1])tr[tr[rt].ch[1]].lzy+=tr[rt].lzy,tr[tr[rt].ch[1]].id+=tr[rt].lzy;tr[rt].lzy=0;}}void pushup(int rt){tr[rt].siz=1+tr[tr[rt].ch[0]].siz+tr[tr[rt].ch[1]].siz;tr[rt].sum=tr[rt].val+tr[tr[rt].ch[0]].sum+tr[tr[rt].ch[1]].sum;}void split(int now,int k,int &x,int &y){if(!now){x=y=0;return ;}pushdown(now);if(k==tr[now].id){y=tr[now].ch[1],tr[now].ch[1]=0,x=now;pushup(x);return ;	}if(k>=tr[now].id)x=now,split(tr[now].ch[1],k,tr[x].ch[1],y),pushup(x);else y=now,split(tr[now].ch[0],k,x,tr[y].ch[0]),pushup(y);}int merge(int a,int b){if(!a||!b)return a+b;pushdown(a);pushdown(b);if(tr[a].rnd<tr[b].rnd){tr[a].ch[1]=merge(tr[a].ch[1],b);pushup(a);return a;}tr[b].ch[0]=merge(a,tr[b].ch[0]);pushup(b);return b;}public:void insert(int ip,int k){int x1,y1,x2,y2;split(root,k-1,x1,y1);split(x1,k-2,x2,y2);if(y1)tr[y1].lzy++,tr[y1].id++;if(y2)tr[y2].val=tr[y2].sum=0;root=merge(merge(x2,y2),merge(newnode(ip!=k,k),y1));}int query(){return tr[root].sum;}void clear(){for(int i=1;i<=tot;i++)tr[i].ch[0]=tr[i].ch[1]=tr[i].val=tr[i].rnd=tr[i].siz=tr[i].lzy=tr[i].id=0;root=tot=0;}
}T; 
signed main(){int tt;read(tt);init();while(tt--){read(n);read(m);ans=0;for(int i=1,x,y;i<=m;i++)read(x),read(y),T.insert(x,y);//,T.Search();int t=T.query();printf("%d\n",C(n+n-t-1,n));T.clear();}return 0;
}

谢谢!!!

这篇关于[CF1558D]Top-Notch Insertions的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/816975

相关文章

PostgreSQL 17即将发布,新功能Top 3

按照计划,PostgreSQL 17 即将在 2024 年 9 月 26 日发布,目前已经发布了第一个 RC 版本,新版本的功能增强可以参考 Release Notes。 本文给大家分享其中 3 个重大的新增功能。 MERGE 语句增强 MERGE 语句是 PostgreSQL 15 增加的一个新功能,它可以在单个语句中实现 INSERT、UPDATE 以及 DELETE 操作,非常适合数据

AIGC与数据分析融合,引领商业智能新变革(TOP企业实践)

AIGC与数据分析融合,引领商业智能新变革(TOP企业实践) 前言AIGC与数据分析融合 前言 在当今数字化时代,数据已成为企业发展的核心资产,而如何从海量数据中挖掘出有价值的信息,成为了企业面临的重要挑战。随着人工智能技术的飞速发展,AIGC(人工智能生成内容)与数据分析的融合为企业提供了新的解决方案。 阿里巴巴作为全球领先的科技公司,一直致力于探索和应用前沿技术,以提升企业

linux top命令介绍以及使用

文章目录 介绍 `top` 命令1. `top` 的基本功能2. 如何启动 `top`3. `top` 的输出解释系统概况任务和 CPU 使用情况内存和交换空间进程信息 4. 常用操作 总结查看逻辑CPU的个数查看系统运行时间 介绍 top 命令 top 是一个在类 Unix 系统中广泛使用的命令行工具,用于实时显示系统的资源使用情况。它提供了有关 CPU、内存、进程等的详细

优化采样参数提升大语言模型响应质量:深入分析温度、top_p、top_k和min_p的随机解码策略

当向大语言模型(LLM)提出查询时,模型会为其词汇表中的每个可能标记输出概率值。从这个概率分布中采样一个标记后,我们可以将该标记附加到输入提示中,使LLM能够继续输出下一个标记的概率。这个采样过程可以通过诸如 temperature 和 top_p 等参数进行精确控制。但是你是否曾深入思考过temperature和top_p参数的具体作用? 本文将详细解析并可视化定义LLM输出行为的

[LeetCode] 692. Top K Frequent Words

题:https://leetcode.com/problems/top-k-frequent-words/ 题目大意 对于 string[] words,输出 出现频率前k高的 word,顺序 为 word 出现的频率 由高到低 ,频率相同的 word 按 字符排序。 思路 其实是对words中的所有word进行一个排序。 排序有两个规则: 1.word 在 words中出现的次数。 2.

系统设计:Top K Problem (Heavy Hitters)

System Design Interview - Top K Problem (Heavy Hitters) https://www.youtube.com/watch?v=kx-XDoPjoHw&t=1068s

【高校科研前沿】三峡大学黄进副教授等人在环境科学Top期刊JCP发文:人类活动如何在气候变化下影响和降低生态敏感性:以中国长江经济带为例

文章简介 论文名称:How human activities affect and reduce ecological sensitivity under climate change: Case study of the Yangtze River Economic Belt, China(人类活动如何在气候变化下影响和降低生态敏感性:以中国长江经济带为例) 第一作者及单位

Js中window.parent ,window.top,window.self详解

在应用有frameset或者iframe的页面时,parent是父窗口,top是最顶级父窗口(有的窗口中套了好几层frameset或者iframe),self是当前窗口, opener是用open方法打开当前窗口的那个窗口。   window.self 功能:是对当前窗口自身的引用。它和window属性是等价的。 语法:window.self 注:window、self、windo

sql优化------查询整个表按照某个字段排序后的前几条Top-N SQL

1.下图通过执行计划可以看出,查看大表前n条数据 其实就是Oracle中实现TOP N   后续补充

海量数据取top K问题

一个列表中有1亿个数据,需要取出其中最大的前100个数据,如何尽可能的降低时间复杂度? 最容易想到的方法是先对这1亿个数据排序,然后取出最大的100个数据,这样的话时间复杂度就是O(nlogn),显然方法不合适。 可以考虑的方法如下: 1.把这个列表截取成1000个子列表; 2.然后分别找出这1000个子列表中的最大的100个数据; 3.把这1000个子列表中的100个数据全部放到一个新