2015多校赛第六场

1008:Hiking

题意:There are nn people and ii-th people will go out if the number of people going out if no less than l_{i} + 1li+1 and no larger than r_{i} + 1ri+1. You need to invite them one by one to make the number of people going out as large as possible.

思路:贪心做。。对于当前我们可以邀请的人,先邀请 r 小的,然后维护当前可以邀请的人就行了,把当前能邀请的然放进一个优先队列,每次取出 r 最小的,但是 r 得不小于当前已经参加的人数。至于怎么找当前可以邀请的人, 先把所有的[l, r]按 l 升序排列,,然后逐个添加到优先队列里就好了。所以会有两次排序,,一次按 l ,一次按 r


#pragma warning(disable:4996)
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#define N 100010
using namespace std;

struct line{
	int l, r, id;
	bool operator<(const line&op)const{
		return r > op.r;
	}
};

bool cmp(const line&a, const line&b){
	if (a.l == b.l)return a.r < b.r;
	return a.l < b.l;
}

line a[N];
bool vis[N];
int ans[N];
priority_queue<line>q;

int main(){
	int t;
	scanf("%d", &t);
	while (t--){
		int n;
		scanf("%d", &n);
		memset(vis, false, sizeof vis);
		memset(ans, 0, sizeof ans);
		while (!q.empty())q.pop();
		for (int i = 1; i <= n; i++)scanf("%d", &a[i].l);
		for (int i = 1; i <= n; i++){
			scanf("%d", &a[i].r);
			a[i].id = i;
		}

		sort(a + 1, a + 1 + n, cmp);

		int cnt = 0;

		int j = 1;
		for (int i = 0; i < n; i++){
			for (; j <= n; j++){
				if (a[j].l <= i){
					q.push(a[j]);
				}
				else break;
			}
			if (q.empty())break;
			line now = q.top();
			while (now.r < i){
				q.pop();
				if (q.empty()){
					break;
				}
				now = q.top();
			}
			if (q.empty())break;
			ans[i] = now.id;
			vis[now.id] = true;
			cnt++;
			q.pop();
		}
		if (ans[0] == 0){
			printf("0\n1");
			for (int i = 2; i <= n; i++)printf(" %d", i);
			printf("\n");
		}
		else{
			printf("%d\n%d", cnt, ans[0]);
			for (int i = 1; i < cnt; i++)printf(" %d", ans[i]);
			for (int i = 1; i <= n; i++){
				if (vis[i] == false)printf(" %d", i);
			}
			printf("\n");
		}

	}
	return 0;
}


1011:Key Set

题意:For a given set {1, 2, . . . , nn}, you are to find the number of nonempty subsets with even sum.

思路:答案就是2^( n- 1) - 1。。至于为什么,找规律也行。规范点的方法就是考虑{2,3,4,......n}的集合。共有2^( n- 1) - 1个非空的子集,然后

          对于每一个子集,若sum为偶数,就不管了,若sum为奇数就把 1 加进去,就成偶数了。O(∩_∩)O


#include <iostream>
#include <cstdio>

using namespace std;

long long pow( long long n )
{
    long long ans = 1;
    long long base = 2;
    while( n )
    {
        if( n&1 )
            ans = base*ans%1000000007;
        base = base * base %1000000007;
        n>>=1;
    }
    return ans;
}

int main()
{
    int t;
    cin >> t;
    while( t-- )
    {
        long long n;
        scanf("%I64d", &n);
        long long ans = pow( n-1 ) -1;
        printf("%I64d\n", ans);
    }
    return 0;
}

你可能感兴趣的:(2015多校赛第六场)