2022 ccpc广州站 E. Elevator

Problem - E - Codeforces

E. Elevator

题意:有一栋有m层的楼,有n部电梯从1到m。第i个电梯再ai时刻上升。每一层有一个按钮,可以让第一个到达该层的电梯停1秒,如果有多个电梯同时到某一层,下标靠前的被视为第一台到的电梯。

现在要求第i个可以第一个到m层楼至少要按多少次按钮,输出i为1到n的答案。

思路:离线处理 + 树状数组

array或者PII存入aii值,按照ai从小到大排序。按ai从小到大依次处理得到i的答案。

对于第i个下标来说,答案就是前面处理的数量 乘以 当前ai , 之后 减去 前面处理的aj之和,再加上前面处理的下标在当前i前面的,因为它们是ai - aj + 1,而在当前下标之后的是ai - aj

注意第一层和第m层按电梯没有用(
注意按从小到大时,如果ai == aj,那么需要让下标小的在前面。

第一种,观察出按小到大的性质。

发现,这个时候只有在当前下标前面的才需要加1,其他的都是到当前ai就行。

具体代码实现:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;

// #define Multiple_groups_of_examples
#define int_to_long_long
#define IOS std::cout.tie(0);std::cin.tie(0)->sync_with_stdio(false); // 开IOS,需要保证只使用Cpp io流 *
#define dbgnb(a) std::cout << #a << " = " << a << '\n';
#define dbgtt cout<<" !!!test!!! "<<'\n';
#define rep(i,x,n) for(int i = x; i <= n; i++)

#define all(x) (x).begin(),(x).end()
#define pb push_back
#define vf first
#define vs second

typedef long long LL;
#ifdef int_to_long_long
#define int long long
#endif
typedef pair<int,int> PII;

const int INF = 0x3f3f3f3f;
const int N = 2e5 + 21;


template <class T>
struct Fenwick { 
    int n;
    vector<T> a;
    Fenwick(const int &n = 0) : n(n), a(n, T()) {}
    void modify(int i, T x) {
        for (i++; i <= n; i += i & -i) {
            a[i - 1] += x;
        }
    }
    T get(int i) {
        T res = T();
        for (; i > 0; i -= i & -i) {
            res += a[i - 1];
        }
        return res;
    }
    T sum(int l, int r) { // [l, r] *这里已经改过
        return get(r + 1) - get(l);
    }
    int kth(T k) {
        int x = 0;
        for (int i = 1 << __lg(n); i; i >>= 1) {
            if (x + i <= n && k >= a[x + i - 1]) {
                x += i;
                k -= a[x - 1];
            }
        }
        return x;
    }
};
void solve() {
	int n,m; cin>>n>>m;
	Fenwick<int> tr(n + 1);
	vector<array<int,2>> sg(n);
	for(int i = 1; i <= n; ++i) {
		cin>>sg[i-1][0];
		sg[i-1][1] = i;
	}
	sort(all(sg));
	int sum = 0;
	vector<int> ans(n + 1);
	for(int i = 0; i < n; ++i) {
		int id = sg[i][1];
		int v = sg[i][0];
		sum += v;
		ans[id] = (v * (i + 1)) - sum + tr.sum(1,id);
		tr.modify(id, 1);
		if(ans[id] > m - 2) ans[id] = -1;
	}
	for(int i = 1; i <= n; ++i) cout<<ans[i]<<'\n';
}
#ifdef int_to_long_long
signed main()
#else
int main()
#endif

{
	IOS;
	#ifdef Multiple_groups_of_examples
	int T; cin>>T;
	while(T--)
	#endif
	solve();
	return 0;
}
void inpfile() {
	#define mytest
	#ifdef mytest
	freopen("ANSWER.txt", "w",stdout);
	#endif
}

第二种,两个树状数组,一个记录val,一个记录在当前下标前面的个数和在当前下标后面的个数。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;

// #define Multiple_groups_of_examples
#define int_to_long_long
#define IOS std::cout.tie(0);std::cin.tie(0)->sync_with_stdio(false); // 开IOS,需要保证只使用Cpp io流 *
#define dbgnb(a) std::cout << #a << " = " << a << '\n';
#define dbgtt cout<<" !!!test!!! "<<'\n';
#define rep(i,x,n) for(int i = x; i <= n; i++)

#define all(x) (x).begin(),(x).end()
#define pb push_back
#define vf first
#define vs second

typedef long long LL;
#ifdef int_to_long_long
#define int long long
#endif
typedef pair<int,int> PII;

const int INF = 0x3f3f3f3f;
const int N = 2e5 + 21;

template <class T>
struct Fenwick { 
    int n;
    vector<T> a;
    Fenwick(const int &n = 0) : n(n), a(n, T()) {}
    void modify(int i, T x) {
        for (i++; i <= n; i += i & -i) {
            a[i - 1] += x;
        }
    }
    T get(int i) {
        T res = T();
        for (; i > 0; i -= i & -i) {
            res += a[i - 1];
        }
        return res;
    }
    T sum(int l, int r) { // [l, r] *这里已经改过
        return get(r + 1) - get(l);
    }
    int kth(T k) {
        int x = 0;
        for (int i = 1 << __lg(n); i; i >>= 1) {
            if (x + i <= n && k >= a[x + i - 1]) {
                x += i;
                k -= a[x - 1];
            }
        }
        return x;
    }
};
void solve() {
	int n,m; cin>>n>>m;
	Fenwick<LL> tr1(n + 21), tr2(n + 21);
	vector<array<int,2>> sg(n);
	for(int i = 1; i <= n; ++i) {
		cin>>sg[i-1][1];
		sg[i-1][0] = i;
	}
	sort(all(sg), [&](array<int,2> pre, array<int,2> suf) {
		if(pre[1] == suf[1]) return pre[0] < suf[0];
		return pre[1] < suf[1];
	});
	vector<int> ans(n + 1);
	for(int i = 0; i < n; ++i) {
		int id = sg[i][0];
		int v = sg[i][1];
		int left = tr2.sum(1, id), right = tr2.sum(id, n);
		int vleft = tr1.sum(1, id), vright = tr1.sum(id, n);
		ans[id] = left * (v + 1) - vleft + right * v - vright;
		if(ans[id] > m - 2) ans[id] = -1;
		tr1.modify(id, v);
		tr2.modify(id, 1);
	}
	for(int i = 1; i <= n; ++i) cout<<ans[i]<<'\n';
}
#ifdef int_to_long_long
signed main()
#else
int main()
#endif

{
	IOS;
	#ifdef Multiple_groups_of_examples
	int T; cin>>T;
	while(T--)
	#endif
	solve();
	return 0;
}
void inpfile() {
	#define mytest
	#ifdef mytest
	freopen("ANSWER.txt", "w",stdout);
	#endif
}

你可能感兴趣的:(算法题,c语言,算法,开发语言)