zoukankan      html  css  js  c++  java
  • LZU 第四届校赛

    链接:http://oj.lovelyanqi.com/contest/3

    H:

    首先翻译一下权值,意思就是将原来排列中的 (i) 换成了权值排名为第 (i) 个的数,
    我们发现,只需要20位的排列就可以占满 (10^18) 个排名了,所以只需要先把排列前面所有的位置答案算好,
    然后暴力统计排列的后 (20) 位即可
    如果不满 (20) 位就更可以暴力了

    时间复杂度 (O(20*m))

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<cmath>
    #include<stack>
    #include<queue>
    using namespace std;
    typedef long long ll;
    
    const int maxn = 100010;
    
    int n, m;
    ll ans = 0, b[maxn], fac[30], p[maxn];
    
    
    struct Num{
    	int id, a;
    	
    	bool operator < (const Num &x) const{
    		return a < x.a;
    	}
    }a[maxn];
    
    int v[30], c[30];
    ll calc(ll sum){
    	for(int i = 1 ; i <= 20 ; ++i) v[i] = 1;
    	ll tmp = sum;
    	
    	for(int i = 1 ; i <= 20 ; ++i){
    		int t = tmp / fac[20 - i];
    		int cnt = 0;
    		for(int j = 1 ; j <= 20 ; ++j){
    			if(v[j]){
    				if(cnt == t){
    					c[i] = j;
    					v[j] = 0;
    					break;
    				}
    				++cnt;
    			}
    		}
    		tmp %= fac[20 - i];
    	}
    //	for(int i = 1 ; i <= 19 ; ++i) printf("%d ", c[i]); printf("
    ");
    	
    	if(n < 20){
    		int d = 20 - n;
    		for(int i = 1 ; i <= n ; ++i){
    			p[i] = a[c[i + d] - d].id;
    		}
    	} else{
    		int d = n - 20;
    		for(int i = n - 19 ; i <= n ; ++i){
    			p[i] = a[c[20 - (n - i)] + d].id;
    		}
    	}
    	
    //	for(int i = 1 ; i <= n ; ++i) printf("%d ", p[i]); printf("
    ");
    	
    	ll res = 0;
    
    	if(n < 20) {
    		for(int i = 1 ; i <= n ; ++i){
    			ll f = (i & 1) ? 1ll : -1ll;
    			res += f * p[i];
    		} 
    	} else{
    		for(int i = n - 19 ; i <= n ; ++i){
    			ll f = (i & 1) ? 1ll : -1ll;
    			res += f * p[i];
    		}	
    	}
    	
    	return res; 
    }
    
    ll read(){ ll s=0,f=1; char ch=getchar(); while(ch<'0' || ch>'9'){ if(ch=='-') f=-1; ch=getchar(); } while(ch>='0' && ch<='9'){ s=s*10+ch-'0'; ch=getchar(); } return s*f; }
    
    int main(){
    	fac[0] = 1; ll sum = 0;
    	for(int i = 1 ; i <= 20 ; ++i) fac[i] = fac[i - 1] * i;
    //	for(int i = 1 ; i <= 20 ; ++i) printf("%lld ", fac[i]); printf("
    ");
    
    	n = read();
    	for(int i = 1 ; i <= n ; ++i) a[i].a = read(), a[i].id = i; 
    	
    	sort(a + 1, a + 1 + n);
    	for(int i = 1 ; i <= n ; ++i) p[i] = a[i].id;
    	if(n >= 20){
    		for(int i = 1 ; i <= n - 20 ; ++i){
    			ll f = (i & 1) ? 1ll : -1ll; 
    			sum += f * p[i];
    		}	
    	}
    //	for(int i = 1 ; i <= n ; ++i) printf("%d ", a[i].id); printf("
    ");
    
    	m = read();
    	for(int i = 1 ; i <= m ; ++i) b[i] = read();
    	
    	if(n < 20){
    		ans = 0;
    	} else{
    		ans = sum * m;
    	}
    	for(int i = 1 ; i <= m ; ++i){
    		--b[i];
    		ans += calc(b[i]);
    	}
    	
    	printf("%lld
    ", ans); 
    	
    	return 0;
    }
    
  • 相关阅读:
    bzoj 3594: [Scoi2014]方伯伯的玉米田
    普通平衡树(指针splay)
    codeforces 475D. CGCDSSQ
    php 购物车功能
    PHP现阶段发现的不足点
    php 多维数据根据某个或多个字段排序
    redis可视化辅助工具
    Redis在window下安装以及配置
    hive数据操作
    hive 表分区操作
  • 原文地址:https://www.cnblogs.com/tuchen/p/14025352.html
Copyright © 2011-2022 走看看