2020-2021 ACM-ICPC Latin American Regional
K - Keylogger
就是你可以显然的发现一个
设
然后发现矩阵的每一行是单调递增的!
前缀和维护一下
二!分!
做完了!
查看代码
#include<bits/stdc++.h>
const int mod=1e9+7;
using namespace std;
int k,l,n,t[755][755],p[100005],tot,dp[10005][755];
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>k>>l;
for(int i=1;i<=k;++i){
for(int j=1;j<=k;++j){
cin>>t[i][j];
}
}
cin>>n;
for(int i=1;i<n;++i)cin>>p[i];
for(int i=1;i<=k;++i)dp[n][i]=i;
for(int i=n-1;i>=1;--i){
for(int j=1;j<=k;++j){
dp[i][j]=dp[i][j-1];
int pos1=upper_bound(t[j]+1,t[j]+1+k,p[i]+l)-t[j];
int pos2=lower_bound(t[j]+1,t[j]+1+k,p[i]-l)-t[j];
int x1=dp[i+1][pos1-1],x2=dp[i+1][pos2-1];
dp[i][j]=(1ll*dp[i][j]+1ll*x1-1ll*x2+1ll*mod)%mod;
}
}
cout<<dp[1][k];
return 0;
}
B - Beautiful Mountains
考虑一个事情,假设一个区间
这个东西可以开两个 st 表维护,然后山峰再开一个 st 表。
出现
查看代码
#include<bits/stdc++.h>
using namespace std;
int n,m,a[100005],dp[100005][20],lg[100005],dp2[100005][20],dp3[100005][20];
void work(){
for(int j=1;j<=lg[n];++j){
for(int i=1;i+(1<<j)-1<=n;++i){
dp[i][j]=min(dp[i][j-1],dp[i+(1<<j-1)][j-1]);
}
}
for(int j=1;j<=lg[n];++j){
for(int i=1;i+(1<<j)-1<=n;++i){
dp2[i][j]=max(dp2[i][j-1],dp2[i+(1<<j-1)][j-1]);
}
}
for(int j=1;j<=lg[n];++j){
for(int i=1;i+(1<<j)-1<=n;++i){
if(a[dp3[i][j-1]]>a[dp3[i+(1<<j-1)][j-1]])dp3[i][j]=dp3[i][j-1];
else dp3[i][j]=dp3[i+(1<<j-1)][j-1];
}
}
return;
}
int calc1(int lt,int rt){
int base=lg[rt-lt+1];
if((1<<base)==rt-lt+1)return dp[lt][base];
return min(dp[lt][base],dp[rt-(1<<base)+1][base]);
}
int calc2(int lt,int rt){
int base=lg[rt-lt+1];
if((1<<base)==rt-lt+1)return dp2[lt][base];
return max(dp2[lt][base],dp2[rt-(1<<base)+1][base]);
}
int calc3(int lt,int rt){
int base=lg[rt-lt+1];
if((1<<base)==rt-lt+1)return dp3[lt][base];
if(a[dp3[lt][base]]>a[dp3[rt-(1<<base)+1][base]])return dp3[lt][base];
return dp3[rt-(1<<base)+1][base];
}
bool check(int l,int r){
int k=calc3(l+1,r-1);
if(calc1(l+1,k)>=0&&calc2(k+1,r)<=0)return 1;
return 0;
}
int main(){
cin>>n;
lg[0]=-1;
int lst=0;
for(int i=1;i<=n;++i){
cin>>a[i];
if(a[i]==-1||a[i-1]==-1){
dp[i][0]=dp2[i][0]=0;
}
else dp[i][0]=dp2[i][0]=a[i]-a[i-1];
dp3[i][0]=i;
lg[i]=lg[i>>1]+1;
}
work();
bool flg=0;
for(int i=3;i<=n;++i){
int j=1;
bool vis=0;
while(j+i-1<=n){
if(!check(j,j+i-1)){
vis=1;
break;
}
j+=i;
}
if(!vis&&(j>n||check(j,n)))flg=1;
}
if(flg)cout<<"Y";
else cout<<"N";
}
J - Job Allocator
这有啥好写的啊(
直接暴力啊。。。
查看代码
#include<bits/stdc++.h>
using namespace std;
int n,k;
int sum[9][9][9][9][9][9][9][9];
int cpu[100005][8],tot,num[8];
void add(int x){
int *c=cpu[x],cnt[8];
for(cnt[0]=0;cnt[0]<=c[0];cnt[0]++)
for(cnt[1]=0;cnt[1]<=c[1];cnt[1]++)
for(cnt[2]=0;cnt[2]<=c[2];cnt[2]++)
for(cnt[3]=0;cnt[3]<=c[3];cnt[3]++)
for(cnt[4]=0;cnt[4]<=c[4];cnt[4]++)
for(cnt[5]=0;cnt[5]<=c[5];cnt[5]++)
for(cnt[6]=0;cnt[6]<=c[6];cnt[6]++)
for(cnt[7]=0;cnt[7]<=c[7];cnt[7]++)
sum[cnt[0]][cnt[1]][cnt[2]][cnt[3]][cnt[4]][cnt[5]][cnt[6]][cnt[7]]++;
}
void del(int x){
int *c=cpu[x],cnt[8];
for(cnt[0]=0;cnt[0]<=c[0];cnt[0]++)
for(cnt[1]=0;cnt[1]<=c[1];cnt[1]++)
for(cnt[2]=0;cnt[2]<=c[2];cnt[2]++)
for(cnt[3]=0;cnt[3]<=c[3];cnt[3]++)
for(cnt[4]=0;cnt[4]<=c[4];cnt[4]++)
for(cnt[5]=0;cnt[5]<=c[5];cnt[5]++)
for(cnt[6]=0;cnt[6]<=c[6];cnt[6]++)
for(cnt[7]=0;cnt[7]<=c[7];cnt[7]++)
sum[cnt[0]][cnt[1]][cnt[2]][cnt[3]][cnt[4]][cnt[5]][cnt[6]][cnt[7]]--;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin>>n>>k;
for(int i=1;i<=n;++i){
char op;
int m;
cin>>op;
if(op=='C'){
cin>>m;
++tot;
while(m--){
int x;
cin>>x;
cpu[tot][x-1]++;
}
add(tot);
}
else if(op=='D'){
cin>>m;
del(m);
}
else{
cin>>m;
memset(num,0,sizeof(num));
while(m--){
int x;
cin>>x;
num[x-1]++;
}
cout<<sum[num[0]][num[1]][num[2]][num[3]][num[4]][num[5]][num[6]][num[7]]<<'\n';
}
}
return 0;
}
F - Fascinating Partitions
就是你考虑第
用单调栈维护即可。
查看代码
#include<bits/stdc++.h>
using namespace std;
int n;
long long a[3000005],mini[3000005],dp[8005][8005];
int main(){
ios::sync_with_stdio(0);
cin>>n;
for(int i=1;i<=n;++i)cin>>a[i];
a[0]=mini[0]=1e18;
memset(dp,0x7f,sizeof(dp));
dp[0][0]=0;
for(int i=1;i<=n;++i){
stack<int>stk;
stk.push(0);
for(int j=i;j<=n;j++){
mini[j]=dp[i-1][j-1];
while(a[stk.top()]<=a[j]){
mini[j]=min(mini[stk.top()],mini[j]);
stk.pop();
}
dp[i][j]=min(mini[j]+a[j],(!stk.empty())?dp[i][stk.top()]:(long long)1e18);
stk.push(j);
}
}
sort(a+1,a+n+1);
long long sum=0;
for(int i=1;i<=n;++i){
sum+=a[n-i+1];
cout<<dp[i][n]<<' '<<sum<<'\n';
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!