• NOI.AC NOIP模拟赛 第一场 补记


    NOI.AC NOIP模拟赛 第一场 补记

    candy

    题目大意:

    有两个超市,每个超市有(n(nle10^5))个糖,每个糖(W)元。每颗糖有一个愉悦度,其中,第一家商店中的第(i)颗糖果的愉悦度为(A_i),而第二家商店中的第(i)颗糖果的愉悦度为(B_i)

    在每家商店买的糖果会被打包到一个袋子中(可以在一家商店什么都不买,此时认为这家商店的袋子为空)。因为这两个袋子外观是一样的,所以会从两个袋子中随机选择一个,然后吃光里面的糖果。定义一种买糖果的方案的愉悦度为:吃到的糖果的愉悦度之和的最小可能值。

    求买糖果的愉悦度与买糖果的花费之差的最大值。

    思路:

    显然对于一家店,购买相同数量的糖果,一定选择愉悦度尽量高的更优。

    因此将(A_i)(B_i)从大到小排序,求前缀和。答案就是(max{min(A_i,B_j)-(i+j)W})。枚举每一个(A_i,B_j)作为(min),然后另一个数就可以通过二分求出来。

    时间复杂度(mathcal O(nlog n))

    源代码:

    #include<cstdio>
    #include<cctype>
    #include<algorithm>
    inline int getint() {
    	register char ch;
    	while(!isdigit(ch=getchar()));
    	register int x=ch^'0';
    	while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    	return x;
    }
    typedef long long int64;
    const int N=1e5+1;
    int64 a[N],b[N];
    int main() {
    	const int n=getint(),m=getint();
    	for(register int i=1;i<=n;i++) a[i]=getint();
    	for(register int i=1;i<=n;i++) b[i]=getint();
    	std::reverse(&a[1],&a[n]+1);
    	std::reverse(&b[1],&b[n]+1);
    	for(register int i=1;i<=n;i++) a[i]+=a[i-1];
    	for(register int i=1;i<=n;i++) b[i]+=b[i-1];
    	int64 ans=0;
    	for(register int i=0;i<=n;i++) {
    		const int j=std::lower_bound(&b[0],&b[n]+1,a[i])-b;
    		if(j<=n) ans=std::max(ans,a[i]-(int64)(i+j)*m);
    	}
    	for(register int i=0;i<=n;i++) {
    		const int j=std::lower_bound(&a[0],&a[n]+1,b[i])-a;
    		if(j<=n) ans=std::max(ans,b[i]-(int64)(i+j)*m);
    	}
    	printf("%lld
    ",ans);
    	return 0;
    }
    

    sort

    来源:

    Ufa SATU + Bucharest U Contest J. Reverse Sort

    题目大意:

    一个长度为(n(nle50000))的序列(A)。每次操作可以将一个区间翻转,定义翻转区间([l,r])的代价为(r-l+1)。要通过翻转将这个序列排序,请你构造出代价小小于(2 imes10^7)的一种方案。

    思路:

    (A_iin{0,1})时,用归并排序的思想,每次归并时将左子区间的后缀(1)与右子区间的前缀(0)交换即可。

    而没有(A_iin{0,1})的条件时,我们可以利用快速排序的思想,每次从区间内随机选取一个数(x)作为基准,(le x)的数作为(0)(>x)的数作为(1)。然后内层套用上述归并排序的算法。

    源代码:

    #include<cstdio>
    #include<cctype>
    #include<climits>
    #include<algorithm>
    inline int getint() {
    	register char ch;
    	while(!isdigit(ch=getchar()));
    	register int x=ch^'0';
    	while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    	return x;
    }
    const int N=5e4+1;
    int a[N];
    inline bool check(const int &b,const int &e) {
    	for(register int i=b;i<e;i++) {
    		if(a[i]>a[i+1]) return false;
    	}
    	return true;
    }
    void solve(const int &b,const int &e,const int &x) {
    	if(b==e) return;
    	const int mid=(b+e)>>1;
    	solve(b,mid,x);
    	solve(mid+1,e,x);
    	int p=b,q=e;
    	while(p<=mid&&a[p]<=x) p++;
    	while(q>mid&&a[q]>x) q--;
    	if(p<=mid&&q>mid) {
    		printf("%d %d
    ",p,q);
    		std::reverse(&a[p],&a[q]+1);
    	}
    }
    void solve(const int &b,const int &e) {
    	if(b>=e) return;
    	if(check(b,e)) return;
    	const int x=a[b+rand()%(e-b+1)];
    	solve(b,e,x);
    	for(register int i=b;i<=e;i++) {
    		if(a[i]>x) {
    			solve(b,i-1);
    			solve(i,e);
    			return;
    		}
    	}
    	solve(b,e);
    }
    int main() {
    	srand(998244353);
    	const int n=getint();
    	for(register int i=1;i<=n;i++) a[i]=getint();
    	solve(1,n);
    	puts("-1 -1");
    	return 0;
    }
    
  • 相关阅读:
    POJ 1840 Eqs 二分+map/hash
    【vijos】P1514天才的记忆
    函数介绍
    函数参数和函数返回值
    函数参数和函数返回值
    前端项目里常见的十种报错及其解决办法
    前端项目里常见的十种报错及其解决办法
    BootstrapTable的使用教程
    BootstrapTable的使用教程
    前端js实现打印(导出)excel表格
  • 原文地址:https://www.cnblogs.com/skylee03/p/9686093.html
Copyright © 2020-2023  润新知