zoukankan      html  css  js  c++  java
  • HihoCoder 1384 Genius ACM

    https://cn.vjudge.net/problem/HihoCoder-1384

    题目

        Advanced CPU Manufacturer (ACM) is one of the best CPU manufacturer in the world. Every day, they manufacture n CPU chips and sell them all over the world.

        As you may know, each batch of CPU chips must pass a quality test by the QC department before they can be sold. The testing procedure is as follows:

        1) Randomly pick m pairs of CPU chips from the batch of chips (If there are less than 2m CPU chips in the batch of chips, pick as many pairs as possible.)

        2) For each pair, measure the Relative Performance Difference (RPD) between the two CPU chips. Let Di be the RPD of the i-th pair

        3) Calculate the Sqared Performance Difference (SPD) of the batch according to the following formula:

       [ ext{SPD}=sum D_i^2]

        If there are only 1 CPU in a batch, then the SPD of that batch is $0$.

        4) The batch of chips pass the test if and only if $ ext{SPD}leqslant k$, where $k$ is a preseted constant

        Usually they send all the n CPU chips as a single batch to the QC department every day. As one of the best CPU manufacturer in the world, ACM never fail the test. However, with the continuous improvement of CPU performance, they find that they are at risk!

        Of course they don't want to take any risks. So they make a decision to divide the n chips into several batches to ensure all of them pass the test. What’s more, each batch should be a continuous subsequence of their productions, otherwise the QC department will notice that they are cheating. Quality tests need time and money, so they want to minimize the number of batches.

        Given the absolute performance of the $n$ chips $P_1$ ... $P_n$ mesured by ACM in order of manufacture, your task is to determine the minimum number of batches to ensure that all chips pass the test. The RPD of two CPU chips equals to the difference of their absolute performance.

    Input

        The first line contains a single integer $T$, indicating the number of test cases.

        In each test case, the first line contains three integers $n$, $m$, $k$. The second line contains $n$ integers, $P_1$ ... $P_n$.

        T≤12
        1≤n,m≤5×105
        0≤k≤1018
        0≤Pi≤220
    Output

        For each test case, print the answer in a single line.
    Sample Input

        2
        5 1 49
        8 2 1 7 9
        5 1 64
        8 2 1 7 9

    Sample Output

        2
        1

    题解

    贪心+倍增

    考虑一个区间,为了保险,选最大的和最小的为一对。因为$(a+delta_1)^2+(b-delta_2)^2geqslant a^2+b^2$。

    可以分段排序后归并,分段排序$mathcal{O}(nlog n)$,归并$mathcal{O}(n)$,选对$mathcal{O}(n)$,加起来$mathcal{O}(nlog n)$……

    倍增:pos+step,成功就step*=2,失败就step/=2,step到0时考虑下一区间。

    数据规模有点大,用了读写挂= =

    AC代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<set>
    #include<iomanip>
    
    #define REP(r,x,y) for(register int r=(x); r<(y); r++)
    #define REPE(r,x,y) for(register int r=(x); r<=(y); r++)
    #ifdef sahdsg
    #define DBG(...) printf(__VA_ARGS__)
    #else
    #define DBG(...) (void)0
    #endif
    
    using namespace std;
    typedef long long LL;
    typedef pair<LL, LL> pll;
    typedef pair<int, int> pii;
    
    char ch; int f;
    template <class T>
    inline void read(T &x) {
    	x=0; f=1; do ch=getchar(); while(!isdigit(ch) && ch!='-');
    	if(ch=='-') ch=getchar(),f=-1; while(isdigit(ch)) {x=x*10+ch-'0'; 
    	ch=getchar();} x*=f;
    }
    //template <class T, class ...P> inline void read(T &x, P &...y) {read(x); read(y...);}
    #define MAXN 500007
    
    int n,m;
    LL k;
    int oar[MAXN];
    int arr[MAXN];
    int sd[MAXN];
    int nar[MAXN];
    int pos=0, step=1;
    int l=0;
    inline LL pf(int x) {
    	return (LL)x*x;
    }
    inline bool vali() {
    	memcpy(nar+pos,oar+pos,step*sizeof(int));
    	sort(nar+pos, nar+pos+step);
    	int l1=l, l2=pos, r1=pos, r2=pos+step;
    	int N=pos+step;
    	REP(i,l,N) {
    		if(l2>=r2 || (l1<r1 && nar[l2]>=arr[l1]) ) sd[i]=arr[l1++];
    		else sd[i]=nar[l2++];
    	}
    	int M=min(m+l,(N+l)/2);
    	LL s=0;
    	REP(i,l,M) {
    		s+=pf(sd[i]-sd[N+l-i-1]);
    		if(s>k) return false;
    	}
    	REP(i,l,N) {
    		arr[i]=sd[i];
    	}
    	return true;
    }
    int main() {
    	int t;
    	read(t);
    	while(t--) {
    		read(n); read(m); read(k);
    		pos=0, step=1, l=0;
    		REP(i,0,n) {
    			read(oar[i]);
    		}
    		int ans=0;
    		while(l<n) {
    			ans++;
    			step=1;
    			while(step && pos<n) {
    				if(vali()) {
    					pos+=step;
    					step=min(step*2,n-pos);
    				} else {
    					step/=2;
    				}
    			}
    			l=pos;
    		}
    		printf("%d
    ", ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    异步底层代码实现邮件发送
    MongoDB+Echarts+DWebSocket
    celery定时任务+redis有序集合实现实时访问人数
    位运算+数据库两种方式实现中间件权限操作
    cocoapod 引入url
    pdf转xml
    Flutter项目安卓下载地址
    ios Mac 利用SVN进行cocoapod私有库的使用
    KVO
    类别和类扩展的区别
  • 原文地址:https://www.cnblogs.com/sahdsg/p/10673076.html
Copyright © 2011-2022 走看看