首页 > 其他分享 >CF1843E Tracking Segments

CF1843E Tracking Segments

时间:2023-06-28 22:33:33浏览次数:137  
标签:Tracking rs int Segments CF1843E tr lst ch ls

CF1843E Tracking Segments

VP 的时候本来摆烂了,结果快结束的时候想到了做法(没时间敲了 qwq)。这里提供一种和已有题解不同的思路。

我们发现,对于每个修改,我们可以将该点的值修改为这次修改的时间,未修改的点则赋为 \(n+1\)。这样转化后,区间合法的条件就是区间内小于 \(n+1\) 的值至少要有 $\lfloor \frac{r-l+1}{2} \rfloor+1 $ 个,我们令 \(k = \lfloor \frac{r-l+1}{2} \rfloor+1\),,则最早达到合法条件的时间就是这些值中第 \(k\) 小的。这样一来,我们就可以把问题转化为静态区间第 \(k\) 小,主席树做就行。答案就是所有查询结果中最小值,如果都为 \(n+1\) 则说明无解。

代码:

#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+100;

int n, m;
int root[N], a[N];
int ls[30*N], sum[30*N], rs[30*N],tot;
int read() {
	int x = 0, f = 1;
	char ch = getchar();
	while(ch<'0'||ch>'9') {
		if(ch == '-')f = -1;
		ch = getchar();
	}
	while(ch>='0'&&ch<='9') {
		x = x*10+ch-48;
		ch = getchar();
	}
	return x*f;
}
void change(int &tr, int lst, int l, int r, int p) {
	tr = ++tot;
	sum[tr] = sum[lst]+1;
	if(l == r) return;
	int mid = (l+r)>>1;
	ls[tr] = ls[lst], rs[tr] = rs[lst];
	if(p <= mid) change(ls[tr], ls[lst], l, mid, p);
	else change(rs[tr], rs[lst], mid+1, r, p);
}
int query(int tr, int lst, int l, int r, int kth) {
	if(l == r) return l;
	int mid = (l+r)>>1;
	int tmp = sum[ls[tr]]-sum[ls[lst]];
	if(tmp>=kth) return query(ls[tr], ls[lst], l, mid, kth);
	else return query(rs[tr], rs[lst], mid+1, r, kth-tmp);
}

int T;
struct question{
	int l, r;
}q[N];
int main() {
	T = read() ;
	while(T--){
		
		n = read(), m = read();
		for(int i = 1; i<=m; ++i){
			q[i].l = read();
			q[i].r = read();
		}
		int Q = read();
		for(int i = 1; i<=n; ++i) a[i] = n+1;
		for(int i = 1; i<=Q; ++i){
			int tmp = read();
			a[tmp] = i;
		}
        
		for(int i = 1; i<=n; i++) change(root[i], root[i-1], 1, n+1, a[i]);
		int ans = n+1;
		for(int i = 1; i<=m; i++) {
			int kth = (q[i].r-q[i].l+1)/2+1;
			int tmp = query(root[q[i].r], root[q[i].l-1], 1, n+1, kth);
			if(tmp == n+1) continue;
			else ans = min(ans, tmp);
		}
		if(ans == n+1) puts("-1");
		else printf("%d\n", ans);
		for(int i = 1; i<=tot; ++i){//手动清空防止TLE
			ls[i] = rs[i] = sum[i] =  0;
		}
		for(int i = 1; i<=n; ++i) root[i] = 0;
		tot = 0;
	}

	return 0;
}

标签:Tracking,rs,int,Segments,CF1843E,tr,lst,ch,ls
From: https://www.cnblogs.com/frostwood/p/17512728.html

相关文章

  • CF1843E 二分+前缀和
    题意:给定一个长度为n且均为0的数组,q次单点修改(从0改为1),以及m个基于该数组的区间。规定好区间为:区间内1的个数严格大于0的个数。上述m个区间若存在一个好区间则为合法,问按顺序进行q次单点修改过程中最早出现合法的单次修改编号,若无则输出-1。马后炮思考:对于m个区间,其实际关系......
  • doris 报错: Insert has filtered data in strict mode, tracking url=
    最近使用doris插入数据时,报了如下错误: Inserthasfiltereddatainstrictmode,trackingurl=点击trackingurl的连接地址,可以查看报错具体详情我的程序报错时因为插入的数据长度超过字段长度,所以需要修改对应字段长度。通过命令进行修改即可ALTERTABLEmy_tableMODI......
  • Educational Codeforces Round 4-D. The Union of k-Segments
    原题链接D.TheUnionofk-SegmentstimelimitpertestmemorylimitpertestinputoutputYouaregiven n segmentsonthecoordinateaxis Ox andthenumber k.Thepoint......
  • Codeforces Beta Round #22 (Div. 2 Only)-D. Segments
    原题链接D.SegmentstimelimitpertestmemorylimitpertestinputoutputYouaregiven nInputThefirstlineoftheinputcontainssingleintegernumber n (1 ≤ n ......
  • 【题解】CF193D Two Segments
    题意给定一个\(1\simN\)的排列,在这个排列中选出两段互不重叠的区间,求使选出的元素排序后构成公差为1的等差数列的方案数。选出的两段区间中元素构成的集合相同时视为同一种方案。\(1\leN\le3\times10^5\)。传送门分析如果考虑怎么优化枚举的两个区间的话,发现不太好搞(反正......
  • dba_segments与dba_extents
    好久没写博客了最近在忙的有几点1.RAC+ADG基于阿里云DBFS数据库文件系统,实验训练一周被告知项目内容可能会更改,只剩下ADG容灾。2.挖矿病毒提前防护,客户中毒较多,打了一片片的补丁。3.RAC集群宕机,原因查了两天,发现服务器本身问题,有点无语。4.拆分数据库内容优化及处理,之前没怎......
  • tracking调研
     常用框架有以下三种:      SeparateDetectionandEmbedding(SDE-物体检测,特征提取与物体关联),JOINTDetectionandEmbedding(JDE)(a)Deepsort:SimpleOnlineandRealtimeTrackingwithaDeepAssociationMetricNicolaiWojke,AlexBewley,D......
  • [Algorithm] Disk height (DP + back tracking)
    You'regivenanon-emptyarrayofarrayswhereeachsubarrayholdsthreeintegersandrepresentsadisk.Theseintegersdenoteeachdisk'swidth,depth,......
  • E. Boring Segments (双指针 + 线段树)
    E.BoringSegments(双指针+线段树)题意:给出n条线段的左右端点和权值$l_i$,$r_i$,$w_i$。要求选择一些线段,使得能够从数轴上的1出发,沿着线段走,能够到达m(连通,不是覆盖)。问......
  • Non-zero Segments VJ-HZNU-FPT1
    题意:给定一个序列,可以在任意相邻对中添加任意大小的数使得不存在一个子序列的和为0,求最小添加次数。2<=n<=200000,-109<=ai<=109;思路:用sum求前缀和,用map存该前缀和之前......