首页 > 其他分享 >luogu1972题解

luogu1972题解

时间:2023-12-14 11:13:28浏览次数:23  
标签:nxt right int 题解 tr luogu1972 啊啊啊 MAXN

还是先写被卡的做法吧。
节点的区间用了现用现计算卡常过了。

被卡了一上午,难过。

话说有人说我码风有点抽象。

思路

主席树做法。

a[i] 是贝壳序列。
先求出 nxt,即与 a[i] 相同的下一个 a[j] 的下标 j
p114514[i] 记了值为 \(i\) 的数的下标,循环到序列第 \(j\) 个数的时候,先看看有没有存上一个数的下标,存了就用 locp 存一下,然后更新 p114514[i]

然后对 nxt 建主席树,第 \(i\) 棵树维护一个 01 序列,如果 nxt 在 \(\left[1,i\right]\) 中则标记为 \(0\),否则为 \(1\)。(就是每个线段树代表的其实是一个区间,如果有两个相同值的数在这个区间内会统计下一个忽略上一个)

修改的时候用 locp 存一下每棵线段树要修改的下标,因为每个数和它上一个相等的数是唯一的,如果要修改每次只会修改一个数,开一个数组即可。

每次查询的时候查 root[r] 这颗树上 \(\left[l,r\right]\) 中 \(1\) 的数量即可,不用担心 \(\left[1,l-1\right]\) 这个区间会扣掉树上的一些数,因为记的是 nxt,所以在 \(\left[l,r\right]\) 上不会出现 \(\left[1,l-1\right]\) 区间的数。

写完之后发现可以优化掉 nxt 数组,所以直接去掉了。

代码

#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e6+10; 
int n,a[MAXN],tot,locp[MAXN],p114514[MAXN],root[MAXN],m;
struct SegmentTreeNode{
	int sum,lson,rson;
}tr[MAXN<<5];
int read(){
	int x=0;
	char ch=getchar();
	while(ch<'0'||ch>'9'){ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+(ch^48);ch=getchar();}
	return x;
}
namespace sol{
	int newnode(){
		return ++tot;
	}
	int buildtree(int l,int r){
		int p=newnode();
		tr[p].sum=r-l+1;
		if(l==r)return p;
		#define mid ((l+r)>>1)
		tr[p].lson=buildtree(l,mid);
		tr[p].rson=buildtree(mid+1,r);
		#undef mid
		return p;
	}
	void change(int p1,int &p2,int loc,int l,int r){
		p2=newnode();
		tr[p2].sum=tr[p1].sum-1;
		if(l==r)return;
		#define mid ((l+r)>>1)
		if(loc<=mid){
			change(tr[p1].lson,tr[p2].lson,loc,l,mid);
			tr[p2].rson=tr[p1].rson;
		}else{
			tr[p2].lson=tr[p1].lson;
			change(tr[p1].rson,tr[p2].rson,loc,mid+1,r);
		}
		#undef mid
	}
	int query(int p,int l,int r,int l1,int r1){
		if(l1==l&&r1==r)return tr[p].sum;
		#define mid ((l1+r1)>>1)
		if(r<=mid)return query(tr[p].lson,l,r,l1,mid);
		else if(mid<l)return query(tr[p].rson,l,r,mid+1,r1);
		else return query(tr[p].lson,l,mid,l1,mid)+query(tr[p].rson,mid+1,r,mid+1,r1);
		#undef mid 
	}
	void solve(){
		n=read();
		for(int i=1;i<=n;++i){
			a[i]=read();
		}
		root[1]=buildtree(1,n);
		for(int i=1;i<=n;++i){
			locp[i]=p114514[a[i]];
			p114514[a[i]]=i;
		}
		for(int i=2;i<=n;++i){
			root[i]=root[i-1];
			if(locp[i]!=0)
				change(root[i-1],root[i],locp[i],1,n);
		}
		m=read();
		while(m){
			--m;
			int l,r;
			l=read();r=read();
			printf("%d\n",query(root[r],l,r,1,n));
		}
	}
}
int main(){
	sol::solve();
	return 0;
}

讨厌卡常啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊

标签:nxt,right,int,题解,tr,luogu1972,啊啊啊,MAXN
From: https://www.cnblogs.com/LiJoQiao/p/17900760.html

相关文章

  • Vue + Element UI 实现复制当前行数据功能(复制到新增页面组件值不能更新等问题解决)
    1、需求使用Vue+ElementUI实现在列表的操作栏新增一个复制按钮,复制当前行的数据可以打开新增弹窗后亦可以跳转到新增页面,本文实现为跳转到新增页面。2、实现1)列表页index.vue<el-table><!--其他列--><el-table-columnlabel="操作"width="150"><templateslot-scope=......
  • [CF980D] Perfect Groups 题解
    [CF980D]PerfectGroups题解思路第一个观察就很难观察到:\[ab=x^2,bc=y^2\Longrightarrow\existz,ac=z^2(a,b,c\ne0)\]证明:两个条件式相乘得到:\[ab^2c=x^2y^2\\ac=\dfrac{x^2y^2}{b^2}(b\ne0)\\\becauseb|x^2,b|y^2\\\thereforeb^2|x^2y^2......
  • P1004 [NOIP2000 提高组] 方格取数 题解
    P1004[NOIP2000提高组]方格取数题解题目链接P1004[NOIP2000提高组]方格取数简要思路注意一下输入可以简化为while(std::cin>>x>>y>>val&&x){ //***}运用DP的思想。用一个四维的\(DP\)数组\(dp[i][j][k][l]\)来同时记录两条路径分别走到\((i,j)\)和\((k,......
  • P4463 [集训队互测 2012] calc 题解
    Description一个序列\(a_1,a_2,\dots,a_n\)是合法的,当且仅当:\(a_1,a_2,\dots,a_n\)都是\([1,k]\)中的整数。\(a_1,a_2,\dots,a_n\)互不相等。一个序列的值定义为它里面所有数的乘积,即\(a_1\timesa_2\times\dots\timesa_n\)。求所有不同合法序列的值的和对\(p\)......
  • CF213E Two Permutation 题解
    CF213ETwoPermutations题解题意:给出两个排列$a,b$,长度分别为\(n,m\),你需要计算有多少个$x$,使得\(a_1+x,a_2+x,...a_n+x\)是\(b\)的子序列。\(n\leqm\leq2\times10^5\)分析:一个很自然的思路是直接枚举\(x\),然后只保留\(b\)中值域在\([x+1,x+n]\)......
  • 记一次 Zabbix agent is not available 问题解决
    好久没折腾zabbix,最近遇到一个奇葩的问题,忽然有一台服务器报警“Zabbixagentisnotavailable(ornodatafor30m)”,但是查看监控数据都有,而且在不断的更新开始分析问题、解决问题:1、先检查了一遍配置,都没问题2、检查了一遍server端和agent端的日志,也没有相应的错......
  • CF1500F Cupboards Jumps 题解
    题目链接点击打开链接题目解法感觉是一个融合了许多技巧的题,很巧妙题目要求\(\max(h_i,h_{i+1},h_{i+2})-\min(h_i,h_{i+1},h_{i+2})=w_i\),这可以转化成另一个只和两项有关的形式为:\(\max(|h_i-h_{i+1}|,|h_i-h_{i+2}|,|h_{i+1}-h_{i+2}|)=w_i\)令\(d_i=h_{i+1}-h_i\),所以......
  • springboot-micrometer潜在oom问题解决办法
    在服务中起一个监听Prometheus拉取的线程,在拉取完成之后清理调meterMap中内容比较多的tag,我这边是清理调gateway.requests.代码如下:@ComponentpublicclassPrometheusMeterRegistryFactory{@ResourceprivatePrometheusMeterRegistryprometheusMeterRegistry;......
  • CTFpwnAD世界pwnstack题解及栈溢出两种解法
    问题的出现这题我刚看到时差点没笑出来,但是尝试了一次之后我就笑不出来了。这题给了back_door后门函数,但是如果直接覆盖返回到后门函数起始位置会出现栈溢出问题。到这一步都没有出现问题,而继续ni的话就会卡住。基本上这里看到xmm0就是栈对其问题了。出现问题原因很简单,linux系统一......
  • 【洛谷 P1271】【深基9.例1】选举学生会 题解(计数排序)
    【深基9.例1】选举学生会题目描述学校正在选举学生会成员,有名候选人,每名候选人编号分别从1到,现在收集到了张选票,每张选票都写了一个候选人编号。现在想把这些堆积如山的选票按照投票数字从小到大排序。输入格式输入和以及个选票上的数字。输出格式求出排序后的选票编......