• CodeForces


    https://codeforces.com/problemset/problem/1437/E

    这是有限制的最长上升子序列

    数字之间必须满足list[i] - list[j] >= i - j

    处理的时候就是让list[i] - i,这样就得到了最长不下降子序列,非正数就赋成INF忽略不计,就可以算了,见到大佬门用upper_bounder算的,不太会

    我就用权值线段树动态开点写了这个题,转换成最长不下降子序列最重要!!!

    具体看代码,不好写但是原理很简单

    #include<iostream>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    #include<vector>
    using namespace std;
    const int maxn = 1e6+1111;
    typedef long long ll;
    ll len = 3e9+11;
    
    struct Node{
    	int l,r,ans;
    }tree[maxn*10];
    
    ll INF = 2e9+3;
    
    int cnt = 0;
    int update(int& node,ll be,ll en,ll i,int val){
    	if(node == 0) node = ++cnt;
    	int mid = be + en >> 1;
    	if(be == en){
    		tree[node].ans = val;
    		return 0;
    	}
    	if(i <= mid) update(tree[node].l,be,mid,i,val);
    	else update(tree[node].r,mid+1,en,i,val);
    	int l = tree[node].l;
    	int r = tree[node].r;
    	tree[node].ans = max(tree[l].ans,tree[r].ans);
    	return 0;
    }
    int ask(int node,ll be,ll en,ll LL,ll RR){
    	if(node == 0)  return 0;
    	int mid = be + en >> 1;
    	if(LL <= be && en <= RR) {
    		return tree[node].ans;
    	}
    	int val1 = -1,val2 = -1;
    	if(LL <= mid) val1 = ask(tree[node].l,be,mid,LL,RR);
    	if(RR > mid) val2 = ask(tree[node].r,mid+1,en,LL,RR);
    	return max(val1,val2);
    }
    
    ll list[maxn];
    int ins[maxn];
    ll cns[maxn];
    int dp[maxn];
    
    int n,k;
    int init(){
    	for(int i=0;i<=cnt;i++){
    		tree[i].l = tree[i].r = 0;
    		tree[i].ans = 0;
    	}
    	cnt = 2;
    	return 0;
    }
    
    int cal(int l,int r,int f){
    	int root =1;
    	cnt = 2;
    	int ans = 0;
    	int be = l + 1,en = r;
    	int len = 2e9;
    
    	for(int i=be;i<=en;i++){
    		cns[i] = list[i] - list[l] - (i - be);
    		if(cns[i] <= 0) {
    			cns[i] = INF;
    			ans++;
    		}
    	}
    	
    	ans = 0;
    	for(int i = be;i<=en;i++){
    		if(cns[i] == INF) continue;
    		
    		int a = ask(root,1,len,1,cns[i]);	
    		dp[i] = a+1;
    		ans = max(ans,dp[i]);
    		update(root,1,len,cns[i],dp[i]);
    	}
    	
    	for(int i=0;i<=cnt;i++){
    		tree[i].l = tree[i].r = tree[i].ans = 0;
    	}
    	
    	if(f) return r - l - ans;
    	return r - l - dp[en];
    }
    
    int main(){
    	scanf("%d%d",&n,&k);
    	for(int i=1;i<=n;i++){
    		scanf("%lld",&list[i]);
    	}
    	list[0] = -1000000002;
    	
    	int f = 0;
    	for(int i=1;i<=k;i++){
    		scanf("%d",&ins[i]);
    	}
    	
    	for(int i=2;i<=k;i++){
    		int x = ins[i];
    		int y = ins[i-1];
    		if(list[x] - list[y] < x - y){
    			f = 1;
    			break;
    		}
    	}
    	if(f){
    		printf("-1
    ");
    		return 0;
    	}
    	if(k == 0){
    		int ans = cal(0,n,1);
    		cout<<ans<<endl;
    		return 0;
    	}
    	int ans = 0;
    
    	for(int i=2;i<=k;i++){
    		ans += cal(ins[i-1],ins[i],0);
    	}	
    	
    	ans += cal(ins[k],n,1);
    	ans += cal(0,ins[1],0);
    	cout<<ans<<endl;
    	return 0;
    }
    /*
    100 0
    4 20 52 2 7 36 8 73 9 99 13 19 14 89 32 2 6 2 16 21 47 22 66 23 25 95 28 
    4 29 64 30 31 7 48 32 51 35 37 77 57 40 42 56 40 43 44 46 13 47 12 48 49 
    24 51 69 53 54 98 21 57 59 61 62 52 63 30 68 32 69 39 8 67 71 59 72 81 76 
    77 11 82 85 14 83 33 86 89 89 90 43 96 91 31 93 69 58 94 45 96 2 99
    
    输出 80 
    
    */
    

      

  • 相关阅读:
    Warning: $HADOOP_HOME is deprecated解决方法
    配置hadoop-1.2.1 eclipse开发环境
    Retinex图像增强算法代码
    XML 处理利器 : XStream
    #一周五# win10通用平台,无处不在的Xamarin,msbuild开源,MVP卢建晖的Asp.NET 5系列 (视频)
    javascript两种声明函数的方式的一次深入解析
    Spring AOP (二)
    Spring AOP (一)
    如何成为Android高手
    模拟 POJ 2993 Emag eht htiw Em Pleh
  • 原文地址:https://www.cnblogs.com/lesning/p/13901684.html
Copyright © 2020-2023  润新知