题意:问你有n个长度总和为n的数组 你可以移动数组 但不能移出长度为w的矩形框 问你每一列的最大值是多少?
思路:只有一次询问 我们可以考虑差分来解决 然后对于每一行数组 我们可以用数据结构维护一下区间最大值
#include <bits/stdc++.h> using namespace std; const int inf = 0x3f3f3f3f; const double eps = 1e-6; const int N = 1e6+7; typedef long long ll; const ll mod = 998244353; using namespace std; ll a[N],ans[N],sum[N]; ll st[N][20]; void init(int len){ for(int i=1;i<=len;i++) st[i][0]=a[i]; int m=log2(len)+1; for(int j=1;j<m;j++) for(int i=1;i<=(len-(1<<j)+1);i++) st[i][j]=max(st[i][j-1],st[i+(1<<(j-1))][j-1]); } ll ask(int l,int r){ int k=log2(r-l+1); return max(st[l][k],st[r-(1<<k)+1][k]); } int main(){ ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int n,w; cin>>n>>w; for(int i=1;i<=n;i++){ int l; cin>>l; for(int j=1;j<=l;j++) cin>>a[j]; init(l); for(int j=1;j<=l;j++){ ll x; if(j-(w-l)<1){ x=max(ask(1,j),0ll); ans[j]+=x; ans[j+1]-=x; }else{ x=ask(j-(w-l),j); ans[j]+=x; ans[j+1]-=x; } } for(int j=w;j>max(l,w-l);j--){ ll x; int po=l-(w-j); if(po+(w-l)>l){ x=max(ask(po,l),0ll); ans[j]+=x; ans[j+1]-=x; }else{ x=ask(po,po+(w-l)); ans[j]+=x; ans[j+1]-=x; } } if(2*l<w){ ll x=max(0ll,ask(1,l)); ans[l+1]+=x; ans[w-l+1]-=x; } } for(int i=1;i<=w;i++){ sum[i]=sum[i-1]+ans[i]; cout<<sum[i]<<" "; } cout<<endl; return 0; }