Wannafly挑战赛19

Wannafly挑战赛19


A. 队列Q

需要支持把一个元素移到队首,把一个元素移到队尾,移到队首就直接放到队首前面那个位置,原位置标为0,队尾同理。

#include <bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;++i)
typedef long long ll;
const int N = 30000200;
using namespace std;
int n,m;
int q[N],hd,x,ed,P[N];
char s[1111];
void F(int x) {
    int p = P[x];
    swap(q[p],q[hd]);
    P[x] = hd;
    hd--;
}
void L(int x){
    int p=P[x];
    swap(q[p],q[ed]);
    P[x]=ed;
    ed++;
}
int main() {
    scanf("%d",&n);
    hd = 500000;
    ed = hd + n - 1;
    rep(i,hd,ed)scanf("%d",&q[i]),P[q[i]]=i;
    hd--;ed++;
    scanf("%d",&m);
    rep(ti,1,m){
        scanf(" %s %d",s,&x);
        if(s[0]=='F'){
            F(x);
        }
        else {
            L(x);
        }
    }
    int f=0;
    rep(i,hd,ed)if(q[i]){
        if(f)printf(" ");f=1;
        printf("%d",q[i]);
    }puts("");
    return 0;
}

B. 矩阵

带限制的最大子矩阵,首先是与不带限制的最大子矩阵一样,最上边的边和底边,然后做最大子段和。带上了0的限制和长度限制,于是写了个双指针,就过了。(讲道理感觉双指针有点假。。。

#include <bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;++i)
typedef long long ll;
const int N = 555;
const ll inf = 1000000000000000LL;
using namespace std;
int R,C,X,Y,Z;
ll mp[N][N], sum[N][N], sum0[N][N], a[N], b[N];
int ck(int l,int r,ll x,ll y) {
    if(r-l+1 <= Y && l<=r && r<=C && x<=Z) return 1;
    return 0;
}
ll solve() {
    ll res=0,ans=a[1],ans0=b[1];
    rep(i,1,C)res=max(res,a[i]);
    int l = 1, r = 1;
    while(l<=r&&r<=C) {
        if(ck(l,r,ans0,ans))res = max(res,ans);
        while(ck(l,r+1,ans0+b[r+1],ans))++r,ans+=a[r],ans0+=b[r],res=max(res,ans);
        if(ck(l,r,ans0,ans))res = max(res,ans);
        ans -= a[l];
        ans0 -= b[l];
        ++l;
        while(a[l]<=0&&l<=C)ans0-=b[l],ans-=a[l],++l;
        while(l>r)++r,ans0+=b[r],ans+=a[r];
        if(ck(l,r,ans0,ans))res = max(res,ans);
    }
    return res;
}
int main() {
    scanf("%d %d %d %d %d",&R,&C,&X,&Y,&Z);
    rep(i,1,R)rep(j,1,C)scanf("%lld",&mp[i][j]);

    rep(i,1,R)rep(j,1,C){
        sum[i][j] = sum[i-1][j] + mp[i][j];
        if(mp[i][j]==0) sum0[i][j] = sum0[i-1][j] + 1;
        else sum0[i][j] = sum0[i-1][j];
    }
    ll ans = 0;
    rep(l,1,R)rep(r,l,min(R,l+X-1)){
        rep(k,1,C) a[k] = sum[r][k]-sum[l-1][k], b[k] = sum0[r][k]-sum0[l-1][k];
        ans = max(ans,solve());
    }
    printf("%lld\n",ans);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/RRRR-wys/p/9275919.html