zoukankan      html  css  js  c++  java
  • 蒟蒻无聊之一

    一道很简单的练手题目
    https://loj.ac/problem/10121#submit_code
    题目大意:
    多次询问区间的完美序列;(完美序列定义为一段连续序列中各个数字都不同)
    求多个区间最长完美序列(不修改)
    分析:
    静态查询:last数组,求最大?dp数组
    (动态查询估计就要莫队了吧)
    last[a[i]]表示数a[i]的上一次出现的位置
    dp[i]表示以第i位结尾的最长完美序列的起始位置的max
    就有:dp[i]=max(dp[i-1],last[a[i]]+1)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!这个dp数组是关键
    最后查询用st表预处理(i-dp[i]+1)就是每个序列的长度
    因为last数组是单调递增的,所以用二分就可以解决一段区间的前段不在该区间内的情况
    能不手写二分就不,边界范围太难掌控了
    code by wzxbeliever

    #include<bits/stdc++.h>
    #define ll long long
    #define lowbit(x) x&(-x)
    #define il inline
    #define ri register int
    using namespace std;
    const int maxn=2e5+5;
    const int maxx=1e6;
    int lg[maxn],last[(maxx<<1)+5],st[maxn][20],s[maxn],f[maxn];
    int n,m;
    il void init(){
    	lg[0]=-1;
    	for(ri i=1;i<=n;i++)lg[i]=lg[i>>1]+1;
    	for(ri j=1;(1<<j)<=n;j++)
    	for(ri i=1;i+(1<<j)-1<=n;i++)
    	st[i][j]=max(st[i][j-1],st[i+(1<<j-1)][j-1]);
    	return;
    } 
    il int askmax(int L,int R){
    	if(L>R)return 0;
    	int k=lg[R-L+1];
    	return max(st[L][k],st[R-(1<<k)+1][k]);
    }
    int main(){ 
    	scanf("%d%d",&n,&m);
    	for(ri i=1,x;i<=n;i++){
    		scanf("%d",&x);
    	s[i]=max(s[i-1],last[x+maxx]+1);
    	f[i]=i-s[i]+1;
    	st[i][0]=f[i];
    	last[x+maxx]=i;
    	}
    	init();
    	for(ri i=1,L,R;i<=m;i++){
    		scanf("%d%d",&L,&R);L++,R++;
    		int pos=lower_bound(s+1+L,s+1+R,L)-s-1;
    		//cout<<"pos="<<pos<<endl;
    	   printf("%d
    ",max(pos-L+1,askmax(pos+1,R)));
    	} 
       return 0;
    }
    
  • 相关阅读:
    (Go)11.九九乘法表示例
    (Go)10.流程控制示例
    (Go)09.指针赋值修改示例
    (Go)08.time示例
    (Go)07.strings与strconv的示例
    (Go)07.Go语言中strings和strconv包示例代码详解02
    (Go)06. Printf格式化输出、Scanf格式化输入详解
    kafka参数在线修改
    vs code golang代码自动补全
    JVM 方法区
  • 原文地址:https://www.cnblogs.com/wzxbeliever/p/12198953.html
Copyright © 2011-2022 走看看