首页 > 其他分享 >C 序列(seq)

C 序列(seq)

时间:2023-10-01 15:34:32浏览次数:41  
标签:cmn seq int res mn tr 序列 rh

Day \(|\Sigma|\)。

模拟赛里面的题,早上降智没调出来。题意大概就是求区间所有子区间的只出现在子区间内的数的最大值的和。

记录一个数 \(i\) 的最左出现位置 \(l_i\) 和最右出现位置 \(r_i\),一个数只在 \([L,R]\) 中出现当且仅当 \([l_i,r_i]\subseteq [L,R]\)。

考虑扫描线,统一处理所有右端点在 \(p\) 处的询问。对每个 \(l\),记录 \(S_l=\sum\limits_{l\le r\le p}w(l,r)\),考虑每次 \(p\) 的移动相当于给 \(S_l\) 加上 \(w(l,p)\)。考虑 \(w(l,p)\) 相比于 \(w(l,p-1)\) 的变化(如果能快速更新 \(w(l,p)\),\(S_l\) 相当于对历史求和),相当于求所有满足 \(r_i=p,l_i\ge l\) 的 \(i\) 的最大值于 \(w(l,p-1)\) 做比较。

这个过程相当于,先令 \(w(l,p)=w(l,p-1)\),然后我们每次插入 \(r_i=p\) 的所有 \(i\),插入一对 \((l_i,p)\) 时相当于对 \(w(1,p),w(2,p)\cdots,w(l_i,p)\) 前缀对 \(i\) 取 \(\max\),直接吉司机线段树即可。

#include <bits/stdc++.h>
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2")
#define mp make_pair
#define pb emplace_back
#define fi first
#define se second
//#define FILE

using namespace std;
#define int long long
typedef long long ll;
typedef pair<int, int> pi;
bool Med;

const int N = 3e5 + 300;
const int inf = N + 1;

int n, q;
int a[N], lp[N], rp[N], ans[N]; 
vector<pi> g[N], qr[N];

struct seg {
	int mn, cmn, ct, cct, sum, hsum; 
	seg () { }
	seg (int _a, int _b, int _c, int _d, int _e, int _f) : 
		mn(_a), cmn(_b), ct(_c), sum(_d), hsum(_e) { }
	seg operator + (const seg &rh) const {
		seg res;
		if (mn == rh.mn) res.mn = mn, res.cmn = min(cmn, rh.cmn), res.ct = ct + rh.ct, res.cct = cmn > rh.cmn ? rh.cct : cct;
		else if (mn < rh.mn) {
			res.mn = mn, res.ct = ct;
			if (cmn == rh.mn) res.cmn = cmn, res.cct = cct + rh.ct;
			else if (cmn < rh.mn) res.cmn = cmn, res.cct = cct;
			else res.cmn = rh.mn, res.cct = rh.ct;
		} else {
			res.mn = rh.mn, res.ct = rh.ct;
			if (mn == rh.cmn) res.cmn = mn, res.cct = ct + rh.cct;
			else if (mn < rh.cmn) res.cmn = mn, res.cct = ct;
			else res.cmn = rh.cmn, res.cct = rh.cct;
		}
		res.sum = sum + rh.sum, res.hsum = hsum + rh.hsum;
		return res;
	}
} tr[N << 2];

int ti[N << 2], lz[N << 2], hlz[N << 2];

#define ls x << 1
#define rs x << 1 | 1
#define mid ((l + r) >> 1)

void build(int l, int r, int x) {
	tr[x] = seg(0, inf, r - l + 1, 0, 0, 0);
	if (l == r) return;
	build(l, mid, ls), build(mid + 1, r, rs);
}

void phis(int x, int c) { ti[x] += c, hlz[x] += c * lz[x], tr[x].hsum += c * tr[x].sum; }
void psum(int x, int c) { lz[x] += c, tr[x].mn += c, tr[x].sum += c * tr[x].ct; } 
void phsum(int x, int c) { hlz[x] += c, tr[x].hsum += c * tr[x].ct; }

void pdn(int x) {
	int mn = min(tr[ls].mn, tr[rs].mn);
	int fl = (tr[ls].mn == mn), fr = (tr[rs].mn == mn);
	if (ti[x]) phis(ls, ti[x]), phis(rs, ti[x]), ti[x] = 0; 
	if (hlz[x]) {
		if (fl) phsum(ls, hlz[x]);
		if (fr) phsum(rs, hlz[x]);
		hlz[x] = 0;
	}
	if (lz[x]) {
		if (fl) psum(ls, lz[x]);
		if (fr) psum(rs, lz[x]);
		lz[x] = 0;
	}
}

void upd(int l, int r, int s, int t, int c, int x) {
	if (l != r) pdn(x);
	if (tr[x].mn > c) return;
	if (s <= l && r <= t && tr[x].mn <= c && tr[x].cmn > c) return psum(x, c - tr[x].mn), void();
	if (s <= mid) upd(l, mid, s, t, c, ls);
	if (t > mid) upd(mid + 1, r, s, t, c, rs);
	tr[x] = tr[ls] + tr[rs];
}

int qry(int l, int r, int s, int t, int x) {
	if (l != r) pdn(x);
	if (s <= l && r <= t) return tr[x].hsum;
	int res = 0;
	if (s <= mid) res += qry(l, mid, s, t, ls);
	if (t > mid) res += qry(mid + 1, r, s, t, rs);
	return res;
} 

int tp[N];

void solve() {
	cin >> n >> q;
	for (int i = 1; i <= n; i++) cin >> a[i], rp[i] = n + 1;
	for (int i = 1; i <= n; i++) rp[a[i]] = i;
	for (int i = n; i; i--) lp[a[i]] = i;
	for (int i = 1; i <= n; i++) g[rp[i]].pb(mp(lp[i], i));
	for (int i = 1, l, r; i <= q; i++)
		cin >> l >> r, qr[r].pb(mp(l, i));
	build(1, n, 1);
	for (int i = 1; i <= n; i++) {
		for (pi p : g[i]) upd(1, n, 1, p.fi, p.se, 1);
		phis(1, 1);
		for (pi p : qr[i]) ans[p.se] = qry(1, n, p.fi, i, 1);
	}
	for (int i = 1; i <= q; i++) cout << ans[i] << '\n';
}

bool Mbe;
signed main() {
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	cerr << (&Med - &Mbe) / 1024 / 1024 << " MB\n";
	#ifdef FILE
		freopen("ex_seq3.in", "r", stdin);
		freopen("A.out", "w", stdout);
	#endif
	int _ = 1;
//	cin >> T;
	while (_--) solve();
	cerr << 1. * clock() / CLOCKS_PER_SEC << " ms\n";
	return 0;
}

标签:cmn,seq,int,res,mn,tr,序列,rh
From: https://www.cnblogs.com/Ender32k/p/17738878.html

相关文章

  • 给PG数据库已有表,已存在列添加序列并设置序列当前值为自增列的最大值
    CREATEORREPLACEFUNCTION"public"."add_sequence_to_table"("p_table_name"text,"p_column_name"text)RETURNS"pg_catalog"."void"AS$BODY$DECLAREmax_valueINTEGER;sequence_nametext;B......
  • Leetcode 1143. 最长公共子序列
    https://leetcode.cn/problems/longest-common-subsequence/description/?envType=study-plan-v2&envId=top-100-liked给定两个字符串text1和text2,返回这两个字符串的最长公共子序列的长度。如果不存在公共子序列,返回0。一个字符串的子序列是指这样一个新的字符串:它......
  • 《Java编程思想第四版》学习笔记32--关于static字段的序列化
    //:CADState.java//Savingandrestoringthestateofa//pretendCADsystem.importjava.io.*;importjava.util.*;abstractclassShapeimplementsSerializable{publicstaticfinalintRED=1,BLUE=2,GREEN=3;privateintxPos,yPos,dimension;p......
  • 9. seqtk seqkit gtftk 总结
    1.背景  在前面小节我们使用了这些软件,因为混合使用比较让人混乱,这里总结理清楚一下.2.seqtk  功能总览如下图所示.2.1seq  这个功能主要是对\(.fasta\)和\(.fastq\)格式的文件进行格式化.\(-l\)  主要是让序列每行显示多少个碱基#每行显示60个氨基酸se......
  • 最大上升子序列和
    题目概述:给定一个序列,求解该序列的最大上升子序列的和解题思路:我们在LIS的集合定义为:以i结尾的上升子序列的最大长度,那其实我们只需要将集合定义改为:以i结尾的上升子序列的最大和即可。#include<iostream>#include<algorithm>#include<cstring>#include<set>#include<v......
  • R语言随机波动模型SV:马尔可夫蒙特卡罗法MCMC、正则化广义矩估计和准最大似然估计上证
    全文链接:http://tecdat.cn/?p=31162最近我们被客户要求撰写关于SV模型的研究报告,包括一些图形和统计输出。本文做SV模型,选取马尔可夫蒙特卡罗法(MCMC)、正则化广义矩估计法和准最大似然估计法估计。模拟SV模型的估计方法:  sim<-svsim(1000,mu=-9,phi=0.97,sigma......
  • R语言Copula对债券时间序列数据的流动性风险进行度量|附代码数据
    全文链接:http://tecdat.cn/?p=32707原文出处:拓端数据部落公众号在金融市场中,债券的流动性风险一直是一个备受关注的问题。流动性风险是指在市场上,债券价格的波动程度受到市场流动性的影响,这种影响可能导致债券价格的剧烈波动,从而影响投资者的收益。因此,对于债券流动性风险的度量......
  • Java序列serialVersionUID字段
    Spring框架默认使用Java的序列化机制,也就是说,Spring默认使用Java的内置序列化器。Java的序列化机制中,每个序列化的对象都有一个serialVersionUID字段,这个字段用来标识序列化对象的版本。Java的序列化机制是这样的:当一个对象被序列化时,Java会先检查对象的类是否有一个名为"serialV......
  • SequoiaDB分布式数据库2023.9月刊
    本月看点速览行业领先!巨杉数据库再度入选Gartner报告再获认可!巨杉数据库蝉联2023「Cloud100China」榜单成果斐然,巨杉数据库获评广东省信息技术应用创新优秀产品和解决方案创新发展,巨杉数据库入选2023信创企业排行榜行业领先!巨杉数据库再度入选Gartner报告  ......
  • 《prufer 序列》小记
    今天模拟赛被卡科技了,学一下这个东西,之前也看到很多次,只不过一直都没学。算法简介这是一种可以将带标号的树,转成唯一的整数序列表示的方法。而在“数树”题中也有大用。算法流程大概是将带标号的\(n\)个节点的数用\([1,n]\)中的\(n-2\)个整数来表示一个树。也可以理解成......