【CF809D】Hitchhiking in the Baltic States

洛谷链接

题目描述

给你长度为 n 的序列,序列中的每个元素 i 有一个区间限制 [li,ri],你从中选出一个子序列,并给它们标号 xi,要求满足 ∀i<j,xi<xj,且 ∀i,xi∈[li,ri]。 问满足条件子序列的长度最长为多少? 1≤n≤3×10^5 , 1≤li≤ri≤10 ^9。

Sol

这是一道毒瘤题(调好久QAQ)

就是让你求一个最长严格上升子序列 , 只不过是每个数有一个取值范围

先想到一个和原来方法类似的dp
d p [ i ] [ j ] dp[i][j] dp[i][j]表示考虑到第 i i i个位置 , 最后选择的数是 j j j的最长上升子序列长度

然而这里 j j j的范围很大,显然不可做

我们考虑换维

根据我们最长上身子序列的二分栈的做法 , 很显然的结论是长度一样的上升子序列 , 要最后一个数最小最好,这样才更有可能变长

于是我们设 d p [ i ] [ j ] dp[i][j] dp[i][j]表示考虑到第 i i i位 , 当前上升子序列的长度为 j j j 的选择的最后一个数的最小值是多少

转移很简单了(注意这里dp实际上是一个前缀max):
假设当前区间是 [ l , r ] [l,r] [l,r]
那么我们就考虑上一位的情况:
首先对任意 j j j , d p [ i ] [ j ] = d p [ i − 1 ] [ j ] dp[i][j]=dp[i-1][j] dp[i][j]=dp[i1][j],这样就不用考虑相同 j j j 的转移了, 因为其他的转移和从 j − 1 j-1 j1转移过来是等价的

  1. d p [ i − 1 ] [ j − 1 ] &lt; l dp[i-1][j-1]&lt;l dp[i1][j1]<l , d p [ i ] [ j ] = m i n ( d p [ i ] [ j ] , l ) dp[i][j]=min(dp[i][j],l) dp[i][j]=min(dp[i][j],l)
  2. d p [ i − 1 ] [ j − 1 ] &gt; = l &ThickSpace; a n d &ThickSpace; d p [ i − 1 ] [ j − 1 ] &lt; r , d p [ i ] [ j ] = m i n ( d p [ i ] [ j ] , d p [ i − 1 ] [ j − 1 ] + 1 ) dp[i-1][j-1]&gt;=l \;and\; dp[i-1][j-1]&lt;r,dp[i][j]=min(dp[i][j],dp[i-1][j-1]+1) dp[i1][j1]>=landdp[i1][j1]<r,dp[i][j]=min(dp[i][j],dp[i1][j1]+1)
  3. d p [ i − 1 ] [ j − 1 ] &gt; = r , 无 转 移 dp[i-1][j-1]&gt;=r , 无转移 dp[i1][j1]>=r,

容易发现情况分为三段

并且我们容易发现一个结论 , 那就是对于一个 i i i , 它的dp值随 j j j的增长而严格单调递增(因为序列严格上升)
显然选的多最后的数就会越大

这样的话dp的转移就是对区间进行操作了,考虑用 S p l a y Splay Splay来维护

情况 1: 这个相当于找到一个小于 l l l的最后一个数的 j j j , 把 j + 1 j+1 j+1赋值为 l l l
情况2 : 这个相当与是找到dp值在 [ l , r ) [l,r) [l,r) 区间内的一段 j j j,把他们的dp值增加1并且下标后移一位(注意可能影响到第三种情况,故要把大于等于 r r r的第一个 j j j给删掉)

插入删除都能做 , 下标后移是什么呢? 其实并不用管 , 因为你会在前面插入一个数 , 下标自动就加1了 , 所以只用 S p l a y Splay Splay实现区间加法就行了

注意要在插入的时候判断是否该dp值已经存在 , 已存在则不满足dp单调的性质 , 要退出不插入

然后就可以愉快地敲起 Splay 了

注意不要被这种数据卡了 QAQ

2999999
1 1000000000
1 1000000000
....

所以每次操作完后随机一个点Splay到根,就可以跑得飞快了…

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<set>
#include<queue>
using namespace std;
inline int read()
{
	int x=0;char ch=getchar();int t=1;
	for(;ch>'9'||ch<'0';ch=getchar()) if(ch=='-') t=-1;
	for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+(ch-48);
	return x*t;
}
const int N=3e5+10;
int n;int l[N],r[N];
#define __ NULL
#define ls son[0]
#define rs son[1]
#define get_size(a) (a? a->size:0)
#define get_son(a) (a->fa->rs==a)
#define get_dp(a) (a? a->dp:-1)
struct node{
	node* son[2];node* fa;int tag;int size;int dp;
	inline void clear(){ls=rs=fa=__;tag=size=dp=0;}
}pool[N];int cnt=0;
node* rt;
inline void update(node* p){p->size=get_size(p->ls)+get_size(p->rs)+1;}
inline void down(node* p)
{
	if(!p) return ;if(!p->tag) return;
	const int x=p->tag;
	if(p->ls) p->ls->tag+=x,p->ls->dp+=x;
	if(p->rs) p->rs->tag+=x,p->rs->dp+=x;
	p->tag=0;return;
}
inline void rotate(node* p){if(!p) return;
	register int k=get_son(p);register node* q=p->fa;
	down(q);down(p);q->son[k]=p->son[k^1];
	if(p->son[k^1]) p->son[k^1]->fa=q;
	if(q->fa) q->fa->son[get_son(q)]=p;
	p->fa=q->fa;q->fa=p;p->son[k^1]=q;
	return update(q);
}
inline void Splay(node* p,node* goal)
{
	if(!p) return;down(p);if(goal==__) rt=p;
	for(;p->fa!=goal;rotate(p)) if(p->fa->fa==goal) continue;else get_son(p)==get_son(p->fa)? rotate(p->fa):rotate(p);
	return update(p);
}
inline node* Find_pre(int X){node* p=rt,*pre=__;while(p) {down(p);if(get_dp(p)>=X) p=p->ls;else pre=p,p=p->rs;} return pre;}
inline node* Find_nxt(int X){node* p=rt,*pre=__;while(p) {down(p);if(get_dp(p)< X) p=p->rs;else pre=p,p=p->ls;} return pre;}
inline void insert(int x)
{
	if(!rt){rt=&pool[cnt++];rt->clear();rt->size=1;rt->dp=x;return;}
	register node* p=rt,*pre=__;
	while(p){
		pre=p;
		if(p->dp==x) return;down(p);
		if(p->dp>x) p=p->ls;else p=p->rs;
	}
	p=&pool[++cnt];p->clear();p->size=1;p->dp=x;p->fa=pre;
	if(pre->dp>x) pre->ls=p; else pre->rs=p;
	return Splay(p,__);
}
inline void Del(node* p)
{
	if(!p) return;Splay(p,__);node* q=p->ls;
	while(q&&q->rs) q=q->rs;
	if(!q) {rt=p->rs;if(p->rs) p->rs->fa=__;p->clear();}
	else {
		Splay(q,__);
		if(p->rs) p->rs->fa=q;if(q) q->rs=p->rs;
		update(q);p->clear();
	}
	return;
}
int main()
{
	srand(19260817);
	n=read();rt=__;
	for(int i=1;i<=n;++i) l[i]=read(),r[i]=read();
	if(!n) return puts("0"),0;
	insert(l[1]);
	for(register int i=2;i<=n;++i) {
		register int L=l[i],R=r[i];
		register node* p=Find_pre(L);
		register node* q=Find_nxt(R);
		Splay(p,__);Splay(q,p);
		if(!p&&!q) {rt->tag+=1;rt->dp+=1;}
		else {
			if(!q) {if(p->rs) p->rs->dp+=1,p->rs->tag+=1;}
			else if(q->ls) q->ls->dp+=1,q->ls->tag+=1;Del(q);
		}
		insert(L);
		p=&pool[rand()%i+1];
		if(p->size) Splay(p,__);
	}
	register node* p=rt;if(!p) return puts("0"),0;
	while(p->rs) p=p->rs;Splay(p,__);
	printf("%d\n",get_size(p->ls)+1);
}

<think>嗯,用户问的是如何研究病原真菌附属染色体上某个在侵染过程中上调的基因的功能。首先,我需要理解附属染色体和核心染色体的区别。附属染色体通常指一些真菌中的额外染色体,可能携带与致病性相关的基因,但具体功能可能不明确。核心染色体则是维持基本生命活动所必需的。 用户提到这个基因在侵染过程中上调,并且在核心和附属染色体上都有拷贝。这意味着可能存在基因复制或水平转移的情况,附属染色体上的拷贝可能有独特的功能。研究附属染色体上的这个基因,可能需要先确认两个拷贝的结构差异,比如启动子区域、编码区是否有变异,是否产生不同的转录本或蛋白异构体。 接下来,功能研究常用的方法包括基因敲除、过表达、RNA干扰等。但因为附属染色体可能不稳定,或者基因拷贝之间有功能冗余,可能需要特异性地针对附属染色体上的拷贝进行敲除。这里可能需要设计特异性的引物或使用CRISPR-Cas9靶向特定序列差异的区域。 另外,表型分析也很重要,比如敲除附属染色体拷贝后,观察真菌的侵染能力、生长速率、孢子形成等是否有变化。同时,比较核心和附属拷贝在侵染不同阶段的表达模式,可能用qPCR或RNA-seq来验证。 还要考虑基因的亚细胞定位,蛋白互作等,比如通过荧光标记或Co-IP找出相互作用蛋白。此外,附属染色体上的基因可能与其他致病因子协同作用,需要分析其调控网络。 不过,可能存在挑战,比如附属染色体的分离和特异性操作,两个拷贝的高度同源性导致难以区分,或者附属染色体在实验室条件下不稳定。可能需要单染色体分离技术或长读长测序来准确区分拷贝。 用户可能的深层需求是理解该基因在致病中的具体作用,以及附属染色体在进化或适应性中的角色。可能需要综合基因组学、分子生物学和表型分析的方法来全面解析。</think>研究附属染色体(accessory chromosome)上特定基因功能需结合基因组特异性、基因冗余性及表型关联性分析,具体步骤可分为以下7个方向: --- ### **1. 基因拷贝特异性验证** **实验设计**: - 设计针对核心/附属染色体拷贝的特异性引物(需基于SNP/Indel差异) - 使用长读长测序(PacBio/Nanopore)验证基因组组装准确性 - 通过染色体流式分选(flow sorting)或显微切割分离附属染色体 **关键点**: 需排除核心染色体同源序列干扰,建议使用Southern blot验证拷贝数 --- ### **2. 时空表达特征解析** **方法**: - 开发等位基因特异性qPCR检测(allele-specific qPCR) - 时空分辨转录组分析(侵染过程时间梯度采样) - 单细胞测序定位表达细胞类型 **发现方向**: 若附属拷贝在侵染中期特异性高表达,可能参与宿主组织穿透阶段 --- ### **3. 染色体定位工程** **创新策略**: - 利用CRISPR/Cas9介导的染色体删除系统(需构建染色体特异性sgRNA) - 开发附属染色体特异性着丝粒标签系统 - 通过原生质体融合构建单体附属染色体菌株 **优势**: 可单独研究附属染色体基因功能而不影响核心基因组 --- ### **4. 表型组学分析** **多维度表型检测**: - 构建基因敲除突变体(需同时处理核心/附属拷贝) - 显微注射反义寡核苷酸实现瞬时沉默 - 表型组学平台检测:侵染钉形成率、吸器发育、ROS爆发响应等 **关键对照**: 需设置核心拷贝敲除、双敲除及回补实验组 --- ### **5. 三维基因组互作** **技术路线**: - Hi-C染色质构象捕获技术 - 4C-seq分析特定基因的远程互作 - 附属染色体三维结构建模 **生物学意义**: 解析附属染色体基因是否通过空间互作调控核心基因组 --- ### **6. 表观遗传调控** **研究维度**: - 全基因组甲基化测序(WGBS) - 组蛋白修饰ChIP-seq(H3K27me3等) - 附属染色体转座子密度分析 **特殊发现可能**: 附属染色体基因可能通过转座子介导的染色质重塑被激活 --- ### **7. 进化动力学模拟** **分析方法**: - 构建系统发育树(包括直系同源/旁系同源关系) - Tajima's D检验选择压力 - 基因转换(gene conversion)事件检测 **理论突破点**: 可能发现附属染色体通过"genetic hitchhiking"机制维持致病基因 --- ### **研究路线图** ```mermaid graph TD A[基因定位验证] --> B[时空表达谱] B --> C[染色体工程] C --> D[表型组学] D --> E[三维互作网络] E --> F[表观调控] F --> G[进化动力学] G --> H[功能整合模型] ``` --- ### **技术难点预警** 1. 附属染色体不稳定性:建议使用低传代菌株并在培养基中添加渗透压稳定剂 2. 基因冗余干扰:建议采用双靶向sgRNA系统同时沉默多拷贝 3. 异源表达困难:可尝试在轮枝孢菌(Verticillium)等近缘种中进行功能互补 建议优先开展单染色体分离与时空转录组分析,可快速定位关键功能窗口期。后续结合CRISPR-C新系统(如CRISPR-Cas12f)进行微型化基因编辑,可提高附属染色体操作效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值