2024.9.24
今日总结:
1:One More Grid Task
首先分析题意:
给定一个n * m的矩阵,求最大子矩阵的权值是多少
首先每一次枚举最小值,然后用二维前缀和找到矩阵最大的左边界和右边界,
用栈去维护一下向上下左右分别能到哪里,时间复杂度O(n^2logm)
点击查看代码
#include <bits/stdc++.h>
using namespace std;
const int inf = 0x3f3f3f3f;
typedef long long ll;
int n,m;
ll ans;
int main()
{
scanf("%d%d",&n,&m);
vector a(n,vector(m,0));
for(int i = 0;i < n;i ++)
{
for(int j = 0;j < m;j ++)
scanf("%d",&a[i][j]);
auto mn = a[i];
vector<ll> pre(m + 1);
for(int ok = i;ok >= 0;ok --)
{
ll total = 0;
for(int j = 0;j < m;j ++)
{
mn[j] = min(mn[j],a[ok][j]);
total += a[ok][j];
pre[j + 1] += total;
}
vector<int> lf(m),rg(m,m);
stack<int> stk;
stk.push(-1);
for(int j = 0;j < m;j ++)
{
while(stk.size() > 1 && mn[j] < mn[stk.top()])
{
rg[stk.top()] = j;
stk.pop();
}
lf[j] = stk.top();
stk.push(j);
}
for(int j = 0;j < m;j ++)
ans = max(ans,ll(pre[rg[j]] - pre[lf[j] + 1]) * mn[j]);
}
}
printf("%lld\n",ans);
return 0;
}
2:学习了exBSGS
写了一道模板题:
点击查看代码
#include<bits/stdc++.h>
using namespace std;
inline int exgcd(int a,int b,int &x,int &y)
{
if(!b)
{
x = 1,y = 0;
return a;
}
int d = exgcd(b,a % b,y,x);
y -= a / b * x;
return d;
}
map <int,int> Hashh;
inline int exBSGS(int a,int b,int p)
{
a %= p,b %= p;
if(b == 1 || p == 1) return 0;
int d,ax = 1,cnt = 0,x,y;
while((d = exgcd(a,p,x,y)) ^ 1)
{
if(b % d) return -1;
b /= d,p /= d;
cnt ++;
ax = 1ll * ax * (a / d) % p;
if(ax == b) return cnt;
}
exgcd(ax,p,x,y);
int inv = (x % p + p) % p;
b = 1ll * b * inv % p;
Hashh.clear();
int t = ceil(sqrt(p)),val = 1;
for(int i = 0;i < t;i ++)
{
Hashh[1ll * b * val % p] = i;
val = 1ll * val * a % p;
}
a = val;
val = 1;
if(!a) return !b ? 1 + cnt : -1;
for(int i = 0,j;i <= t;i ++)
{
j = Hashh.find(val) == Hashh.end() ? -1 : Hashh[val];
if(~j && i * t - j >= 0) return i * t - j + cnt;
val = 1ll * val * a % p;
}
return -1;
}
int main()
{
int a,b,p,ans;
while(scanf("%d%d%d",&a,&p,&b) == 3 && a && b && p)
{
ans = exBSGS(a,b,p);
if(~ans) printf("%d\n",ans);
else puts("No Solution");
}
return 0;
}