zoukankan      html  css  js  c++  java
  • luogu P1704 寻找最优美做题曲线

    题目背景

    nodgd是一个喜欢写程序的同学,前不久(好像还是有点久了)洛谷OJ横空出世,nodgd同学当然第一时间来到洛谷OJ刷题。于是发生了一系列有趣的事情,他就打算用这些事情来出题恶心大家……

    题目描述


    洛谷OJ刷题有个有趣的评测功能,就是系统自动绘制出用户的“做题曲线”。所谓做题曲线就是一条曲线,或者说是折线,是这样定义的:假设某用户在第b[i]天AC了c[i]道题,并且b[i]严格递增,那么该用户的做题曲线就是平面上点(i,c[i])依次连出的一条折线。比如你在第1天做了3道题,第3天做了4道题,第6天做了1道题,那么你在前6天的做题曲线就是从点(1,3)到点(2,4)到点(3,1)的连续折线。
    nodgd同学可以预测出自己未来N天每条能够AC题目的数量,同时有一个很无趣的爱好,就是单调递增,nodgd强迫自己的做题曲线保持严格的单调递增。但是出于某些原因,nodgd在某些日子(共有K天)必须刷题,而且刷题数量一定是预计的数量(体现nodgd的神预测)。nodgd同学想知道,在这样的情况下,自己最多有多少天可以刷题,不过nodgd同学还有大量的数学竞赛题、物理竞赛题、英语竞赛题、美术竞赛题、体育竞赛题……要做,就拜托你来帮他算算了。

    输入输出格式
    输入格式:
    第一行两个正整数,N和K,表示nodgd预测了未来N天每天做题的数量,其中K天必须刷题。

    第二行K个正整数p[i],表示第p[i]天必须刷题(1<=p[i]<=N,保证每个p[i]不同)。

    第三行N个正整数c[i],表示在第i天nodgd可以AC的题目数量必须是c[i]。

    输出格式:
    一行。

    如果能找到严格递增的做题曲线:一个正整数,表示nodgd最多有多少天可以刷题。

    如果找不到严格递增的做题曲线:直接输出“impossible”(不加引号,全是小写字母)。

    输入输出样例

    输入样例#1:

    13 4
    2 13 8 7
    6 10 9 8 9 10 11 16 14 12 13 14 18 
    

    输出样例#1:

    5
    

    说明

    数据范围

    1<=N<=500000,1<=K<=N/2
    1<=p[i]<=N,保证每个p[i]不同,不保证p[i]按大小顺序输入
    1<=c[i]<=10^9

    若果一数在序列内严格比他前面的书大,比后面的数小,那么这个数一定存在于最长上升子序列中
    显然在规定必须选取的连续两天内,比前一天小的和比后一天大的一定不合法,去掉之后便可使规定选取数变为上述数
    删掉不合法数然后求一遍最长上升子序列就好,注意,第七组数据规定了必须要取第0天,这是一个坑点,当然是O(nlogn)的啦~(≧▽≦)/~

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int maxn = 500007;
    int a[maxn],b[maxn],tmp[maxn],len=1,n,m;
    bool tag[maxn];
    bool check() {
    	sort(b+1,b+m+1);
    	for(int i=2;i<=m;++i) {
    		if(a[b[i]]<a[b[i-1]]) {
    			puts("impossible");return 1;
    		}
    	}
    	return 0;
    }
    int mid_serch(int x) {
    	int l=1,r=len;
    	while(l<=r) {
    		int mid=(l+r)>>1;
    		if(tmp[mid]<a[x])l=mid+1;
    		else r=mid-1;
    	}
    	return l;
    }
    int main () {
    	int t=0;
    	//freopen ("a.in","r",stdin);
    	//freopen("a.out","w",stdout);
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=m;i++) {scanf("%d",b+i);if(b[i]==0)t=1;}
    	for(int i=1;i<=n;++i) scanf("%d",a+i);
    	if(check())return 0;
    	for(int i=2;i<=m;i++) 
    		for(int j=b[i-1]+1;j<b[i];++j) 
    			if(a[j]<=a[b[i-1]]||a[j]>=a[b[i]])tag[j]=1;
    	for(int i=1;i<b[1];++i)
            if(a[i]>=a[b[1]])
                tag[i]=true;
    	for(int i=b[m]+1;i<=n;++i)
            if(a[i]<=a[b[m]])
                tag[i]=true;
    	tmp[1]=a[1];
    	for(int i=2;i<=n;++i) {
    		if(tag[i])continue;
    		if(a[i]>tmp[len])tmp[++len]=a[i];
    		else {
    			int pos=mid_serch(i);
    			tmp[pos]=a[i];
    		}
    	}
    	//for(int i=1;i<=len;i++) {
    	//	printf("%d
    ",tmp[i]);
    	//}
    	printf("%d
    ",len+t);
    	return 0;
    }
    
  • 相关阅读:
    Leetcode Reverse Words in a String
    topcoder SRM 619 DIV2 GoodCompanyDivTwo
    topcoder SRM 618 DIV2 MovingRooksDiv2
    topcoder SRM 618 DIV2 WritingWords
    topcoder SRM 618 DIV2 LongWordsDiv2
    Zepto Code Rush 2014 A. Feed with Candy
    Zepto Code Rush 2014 B
    Codeforces Round #245 (Div. 2) B
    Codeforces Round #245 (Div. 2) A
    Codeforces Round #247 (Div. 2) B
  • 原文地址:https://www.cnblogs.com/sssy/p/7741767.html
Copyright © 2011-2022 走看看