关于 O(nS)过
查看原帖
关于 O(nS)过
204989
_Iva楼主2022/9/30 21:55

1e8是可以过......没毛病

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int fl;
inline int rd()
{
	int x = 0, f = 0; char v = 0;
	while(!isdigit(v))
	{
		v = getchar(), f ^= v == '-';
		if(v == 't') fl = 1;
		else if(v == 'x') fl = 2;
	}
	while(isdigit(v)) x = (x << 1) + (x << 3) + (v ^ 48), v = getchar();
	return f ? -x : x;
}
inline void write(int x)
{
	if(x < 0) putchar('-'), write(-x);
	else
	{
		if(x > 9) write(x / 10);
		putchar(x % 10 + 48);
	}
}
inline void writell(ll x)
{
	if(x < 0) putchar('-'), writell(-x);
	else
	{
		if(x > 9) writell(x / 10);
		putchar(x % 10 + 48);
	}
}
const int N = 1e5 + 10;
int c1, c2, c3, c4, num1, num2, num3, num4, n, M;
ll dp[N], sum[N];
inline int mx(int x, int y) {return x < y ? y : x;}
int main()
{
	c1 = rd(), c2 = rd(), c3 = rd(), c4 = rd(), n = rd();
	while(n--)
	{
		num1 = rd(), num2 = rd(), num3 = rd(), num4 = rd(), M = rd(); //减少数组下标调用
		for(int j = 1; j <= M; ++j) dp[j] = 0;
		dp[0] = 1;
		
		num1 = min(num1, M / c1);
		for(int j = M; ~j; --j) sum[j] = sum[j + c1] + dp[j]; //多重背包前缀和优化 
		int L = max(M - num1 * c1, M % c1);
		for(int j = M; j >= c1; --j)
		{
			dp[j] += sum[L] - sum[j];
			--L;
			if(L < 0) L += c1;
		} 
		
		num2 = min(num2, M / c2);
		for(int j = M; ~j; --j) sum[j] = sum[j + c2] + dp[j];
		L = max(M - num2 * c2, M % c2);
		for(int j = M; j >= c2; --j)
		{
			dp[j] += sum[L] - sum[j];
			--L;
			if(L < 0) L += c2;
		} 
		
		num3 = min(num3, M / c3);
		for(int j = M; ~j; --j) sum[j] = sum[j + c3] + dp[j];
		L = max(M - num3 * c3, M % c3);
		for(int j = M; j >= c3; --j)
		{
			dp[j] += sum[L] - sum[j];
			--L;
			if(L < 0) L += c3;
		} 
		
		num4 = min(num4, M / c4);
		for(int j = M; ~j; --j) sum[j] = sum[j + c4] + dp[j];
		L = max(M - num4 * c4, M % c4);
		for(int j = M; j >= c4; --j)
		{
			dp[j] += sum[L] - sum[j];
			--L;
			if(L < 0) L += c4;
		}
		
		writell(dp[M]), putchar('\n');
	}
}
2022/9/30 21:55
加载中...