C-Increase Subarray Sums
题意
给定一个数组,可以对其中的 k k k 个不同元素都加上 x x x,( k k k, x x x 题目已给出),求 k k k 的取值为 0 0 0 到 n n n 时,该数组内连续子段之和的最大值是多少。
考虑用前缀和的思想,求出长度从 1 1 1 到 n n n 时能够拥有的最大连续子段之和,再枚举 k k k 的取值,则该连续子段能够加上的 x x x 的个数为 m i n ( k , j ) min(k,j) min(k,j),其中 j j j 表示当前枚举的子段的长度。
#include <bits/stdc++.h>
#define int long long
#define PII pair<int,int>
using namespace std;
const int N=5050;
const int mod=998244353;
int a[N],s[N],maxx[N];//maxx中存的为长度为i的最大子段和
PII p[N];
void solve(){
int n,x;
cin>>n>>x;
for(int i=1;i<=n;i++){
cin>>a[i];
s[i]=s[i-1]+a[i];
}
int temp;
for(int i=1;i<=n;i++){
temp=-1e9;
for(int j=i;j<=n;j++){
temp=max(temp,s[j]-s[j-i]);
}
maxx[i]=temp;
}
// for(int i=1;i<=n;i++){
// cout<<maxx[i]<<" ";
// }
// cout<<endl;
int res=0;
for(int i=0;i<=n;i++){
res=0;
for(int j=0;j<=n;j++)
res=max(res,maxx[j]+min(i,j)*x);
cout<<res<<" ";
}
cout<<endl;
return ;
}
signed main(){
int t;
cin>>t;
while(t--)
solve();
return 0;
}
D-Cross Coloring
题意
现有一个全为白色的 n ∗ m n * m n∗m 的矩阵,将有 q q q 个操作,每个操作都将选中点 ( x , y ) (x,y) (x,y) 并对其同行及同列的所有方块同时染成 k k k 个颜色中的任意一种(如某方块之前有颜色也将覆盖)。问有多少种不同的涂色方案。
感觉比 C 更简单(bushi),由于每次操作都会覆盖之前的涂色,因此考虑通过逆序处理,记录从后往前遍历到的未被完全覆盖的点数,并对其对应的行列进行标记。
完全覆盖:当该点所在的行和列在之后的操作都将被覆盖。未完全覆盖:该行或该列还没有被涂色。
由于共有 k k k 种颜色,因此每次遇到未完全覆盖的点时,对答案的贡献均为 ∗ k *k ∗k。为优化操作,当所有行或列都已被覆盖时,之前的操作都不再有意义,直接 b r e a k break break 即可。
#include <bits/stdc++.h>
#define int long long
#define PII pair<int,int>
using namespace std;
const int N=2e5+10;
const int mod=998244353;
int hang[N],lie[N];//改行列的状态 如果标1说明之后寄了
PII p[N];
int qsm(int a,int k){
int res=1;
while(k){
if(k&1) res=res*a%mod;
a=a*a%mod;
k/=2;
}
return res;
}
void solve(){
int n,m,k,q;
cin>>n>>m>>k>>q;
int x,y;
memset(hang,0,sizeof(hang));
memset(lie,0,sizeof(lie));
int a=0,b=0;
for(int i=1;i<=q;i++){
cin>>p[i].first>>p[i].second;
}
int ans=0;
for(int i=q;i>=1;i--){
if(!hang[p[i].first]||!lie[p[i].second]){
ans++;
}
if(!hang[p[i].first]){
hang[p[i].first]=1;
a++;
}
if(!lie[p[i].second]){
lie[p[i].second]=1;
b++;
}
if(a==n||b==m)
break;
}
cout<<qsm(k,ans)<<endl;
}
signed main(){
int t;
cin>>t;
while(t--)
solve();
return 0;
}