社区讨论

进制相关问题

P1005[NOIP 2007 提高组] 矩阵取数游戏参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@lo1clkr1
此快照首次捕获于
2023/10/22 18:50
2 年前
此快照最后确认于
2023/11/02 19:10
2 年前
查看原帖
由于这题longlong会爆,于是偷懒手写了个模
CPP
const ll mod = 1e17;
然后如果超出这个范围就取/和%表示高位低位,这样就把一个数用俩longlong表示了。
现在的问题是上面那个mod取1e17和1e15能ac,但是换成1e18,1e13之类的有时会wa一个点,有时会wa两个点,感觉很玄学,又找不出什么原因(猜是加的时候直接爆longlong了?),等有缘的大佬来看看
代码丢下面
CPP
#include <cstring>
#include <cstdio>
#define ll long long
using namespace std;
const ll mod = 1e17;
int n,m;
ll v[83];
struct num {
	ll x,y;
} dp[83][83],ans;
num max(num i,num j) {
	if (i.x > j.x) return i;
	if (i.x < j.x) return j;
	return i.y > j.y ? i : j;
}
num trans(ll b,int i) {
	num p; p.x = 0,p.y = b;
	for (int a = 1 ; a <= i ; ++ a)
		p.x <<= 1,p.y <<= 1,
		p.x += p.y / mod,
		p.y %= mod;
	return p;
}
num plus(num i,num j) {
	i.x += j.x,i.y +=j.y;
	i.x += i.y / mod;
	i.y %= mod;
	return i;
}
int main() {
	scanf("%d%d",&n,&m);
	ans.x = 0,ans.y = 0;
	for (int a = 1 ; a <= n ; ++ a) {
		memset(v,0,sizeof(v));
		memset(dp,0,sizeof(dp));
		for (int b = 1 ; b <= m ; ++ b) scanf("%lld",&v[b]);
		for (int i = 1 ; i < m ; ++ i) {
			for (int l = 1,r = m - i ; r <= m ; ++ l,++ r) {
				num ldp = plus(dp[l - 1][r],trans(v[l - 1],i));
				num rdp = plus(dp[l][r + 1],trans(v[r + 1],i));
				dp[l][r] = max(ldp,rdp);
			}
		}
		num j; j.x = 0,j.y = 0;
		for (int i = 1 ; i <= m ; ++ i)
			dp[i][i] = plus(dp[i][i],trans(v[i],m)),
			j = max(j,dp[i][i]);
		ans = plus(ans,j);
	}
	if (ans.x) printf("%lld",ans.x); printf("%lld\n",ans.y);
	return 0;
}
/*			for (int l = 1,r = m - i ; r <= m ; ++ l,++ r) {
			dp[l][r] = max(dp[l - 1][r] + (v[l - 1] << i),
						   dp[l][r + 1] + (v[r + 1] << i));
			}
		}
		int j = 0;
		if (m > 1) for (int i = 1 ; i <= m ; ++ i)
			dp[i][i] += (v[i] << m),
			j = dp[j][j] < dp[i][i] ? i : j;
		else j = 1,dp[1][1] = v[1] << 1;
		ans += dp[j][j];
*/

回复

0 条回复,欢迎继续交流。

正在加载回复...