HDU 6396 Swordsman(超级读写挂+优先队列)

Description:

Lawson is a magic swordsman with k kinds of magic attributes v 1 , v 2 , v 3 , … , v k . v_1,v_2,v_3,…,v_k. v1,v2,v3,,vk. Now Lawson is faced with n monsters and the i-th monster also has k kinds of defensive attributes a i , 1 , a i , 2 , a i , 3 , … , a i , k a_{i,1},a_{i,2},a_{i,3},…,a_{i,k} ai,1,ai,2,ai,3,,ai,k. If v 1 ≥ a i , 1 a n d v 2 ≥ a i , 2 a n d v 3 ≥ a i , 3 v_1≥a_{i,1} and v_2≥a_{i,2} and v_3≥a_{i,3} v1ai,1andv2ai,2andv3ai,3 and … and v k ≥ a i , k v_k≥a_{i,k} vkai,k, Lawson can kill the i-th monster (each monster can be killed for at most one time) and get EXP from the battle, which means v j v_j vj will increase b i , j b_{i,j} bi,j for j=1,2,3,…,k.
Now we want to know how many monsters Lawson can kill at most and how much Lawson’s magic attributes can be maximized.

Input:

There are multiple test cases. The first line of input contains an integer T T T, indicating the number of test cases. For each test case:

The first line has two integers n n n and k k k ( 1 ≤ n ≤ 1 0 5 , 1 ≤ k ≤ 5 1≤n≤10^5,1≤k≤5 1n105,1k5).

The second line has k k k non-negative integers (initial magic attributes) v 1 , v 2 , v 3 , … , v k v_1,v_2,v_3,…,v_k v1,v2,v3,,vk.

For the next n n n lines, the i-th line contains 2 k 2k 2k non-negative integers a i , 1 , a i , 2 , a i , 3 , … , a i , k , b i , 1 , b i , 2 , b i , 3 , … , b i , k a_{i,1},a_{i,2},a_{i,3},…,a_{i,k},b_{i,1},b_{i,2},b_{i,3},…,b_{i,k} ai,1,ai,2,ai,3,,ai,k,bi,1,bi,2,bi,3,,bi,k.

It’s guaranteed that all input integers are no more than 1 0 9 10^9 109 and v j + ∑ i = 1 n b i , j ≤ 1 0 9 v_{j}+\sum_{i=1}^{n}{b_{i,j}}\le 10^{9} vj+i=1nbi,j109for j = 1 , 2 , 3 , . . . , k j=1,2,3,...,k j=1,2,3,...,k.

It is guaranteed that the sum of all n ≤ 5 × 1 0 5 n ≤5×10^5 n5×105.
The input data is very large so fast IO (like fread) is recommended.

Output:

For each test case:
The first line has one integer which means the maximum number of monsters that can be killed by Lawson.
The second line has k integers v ′ 1 , v ′ 2 , v ′ 3 , … , v ′ k v′_1,v′_2,v′_3,…,v′_k v1,v2,v3,,vk and the i-th integer means maximum of the i-th magic attibute.

Sample Input:

1
4 3
7 1 1
5 5 2 6 3 1
24 1 1 1 2 1
0 4 1 5 1 1
6 0 1 5 3 1

Sample Output:

3
23 8 4

Hint:

For the sample, initial V = [7, 1, 1]
① kill monster #4 (6, 0, 1), V + [5, 3, 1] = [12, 4, 2]
② kill monster #3 (0, 4, 1), V + [5, 1, 1] = [17, 5, 3]
③ kill monster #1 (5, 5, 2), V + [6, 3, 1] = [23, 8, 4]
After three battles, Lawson are still not able to kill monster #2 (24, 1, 1)
because 23 < 24.

题目链接

题目已经提示推荐了超超超超级读写挂Fast IO(fread),经实验普通的读写挂确实会TLE,神奇。

开5个升序排列的优先队列,每个优先队列存储怪兽的一个属性,不断循环弹出可以击破的属性,当一个怪兽所有属性被弹出时即为此怪兽已经GG,此时可以更新升级再循环遍历,直至无法击破任意一个属性跳出循环。

AC代码:

#include 
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define mp make_pair
#define lowbit(x) (x&(-x))
#define XDebug(x) cout<<#x<<"="<
#define ArrayDebug(x,i) cout<<#x<<"["<
#define print(x) out(x);putchar('\n')
#define Fread(x) fastIO::read(x)
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef pair<double,double> PDD;
typedef pair<ll,ll> PLL;
const int INF = 0x3f3f3f3f;
const int maxn = 1e5 + 5;
const int mod = 1e9 + 7;
const double eps = 1e-8;
const double pi = asin(1.0) * 2;
const double e = 2.718281828459;
// 对这道题并不管用的读写挂
template <class T>
inline bool read(T &ret) {
    char c;
    int sgn;
    if (c = getchar(), c == EOF) {
        return false;
    }
    while (c != '-' && (c < '0' || c > '9')) {
        c = getchar();
    }
    sgn = (c == '-') ? -1 : 1;
    ret = (c == '-') ? 0 : (c - '0');
    while (c = getchar(), c >= '0' && c <= '9') {
        ret = ret * 10 + (c - '0');
    }
    ret *= sgn;
    return true;
}
template <class T>
inline void out(T x) {
    if (x < 0) {
        putchar('-');
        x = -x;
    }
    if (x > 9) {
        out(x / 10);
    }
    putchar(x % 10 + '0');
}
// 超超超超超超级牛逼的读写挂
namespace fastIO {
	const int MX = 4e7;
	char buf[MX];
	int c, sz;
	void begin() {
		c = 0;
		sz = fread(buf, 1, MX, stdin);
	}
	template <class T>
	inline bool read(T &t) {
		while (c < sz && buf[c] != '-' && (buf[c] < '0' || buf[c] > '9')) {
			c++;
		}
		if (c >= sz) {
			return false;
		}
		bool flag = 0;
		if (buf[c] == '-') {
			flag = 1;
			c++;
		}
		for (t = 0; c < sz && '0' <= buf[c] && buf[c] <= '9'; ++c) {
			t = t * 10 + buf[c] - '0';
		}
		if (flag) {
			t = -t;
		}
		return true;
	}
}

int main(int argc, char *argv[]) {
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
#endif
	fastIO::begin();
	int T;
	Fread(T);
	for (int Case = 1, N, K; Case <= T; ++Case) {
		Fread(N); Fread(K);
		// 初始能力值
		int Able[6];
		for (int i = 0; i < K; ++i) {
			Fread(Able[i]);
		}
		// 优先队列分别存怪兽的最多五个属性
		priority_queue<PII, vector<PII>, greater<PII> > Monster[6];
		// 杀掉怪兽所获取的属性加强值
		int Profit[maxn][6];
		for (int i = 0; i < N; ++i) {
			for (int j = 0, X; j < K; ++j) {
				Fread(X);
				Monster[j].push(mp(X, i));
			}
			for (int j = 0; j < K; ++j) {
				Fread(Profit[i][j]);
			}
		}
		bool Flag = 1;
		int Cnt = 0;
		// 统计每个怪兽有哪些属性已经可以被击破
		int Statistic[maxn];
		mem(Statistic, 0);
		// 不断更新可以击杀的怪兽
		while (Flag) {
			Flag = 0;
			// 遍历K个属性
			for (int i = 0; i < K; ++i) {
				while (!(Monster[i].empty())) {
					PII Temp = Monster[i].top();
					// 若当前属性可以被击破
					if (Temp.first <= Able[i]) {
						// 弹出并统计
						Monster[i].pop();
						Statistic[Temp.second]++;
						// 若此怪兽所有属性都可被击破则获取属性加强
						if (Statistic[Temp.second] == K) {
							for (int i = 0; i < K; ++i) {
								Able[i] += Profit[Temp.second][i];
							}
							Cnt++;
							Flag = 1;
						}
					}
					else {
						break;
					}
				}
			}
		}
		print(Cnt);
		for (int i = 0; i < K; ++i) {
			out(Able[i]);
			if (i != K - 1) {
				putchar(' ');
			}
		}
		putchar('\n');
	}
#ifndef ONLINE_JUDGE
    fclose(stdin);
    fclose(stdout);
    system("gedit out.txt");
#endif
    return 0;
}

你可能感兴趣的:(HDU 6396 Swordsman(超级读写挂+优先队列))