jzoj6404。[11.04] BアナログNOIP2019

タイトル説明

説明

入力
データは、3つの正の整数のファイルb.in.荘行から読み出され、N、M、N K.次m行行列Aを表す各正の整数

出力は
、ファイルB.OUTに出力されます。いいえ、2つの数字がマシンと大きな値を表します。

サンプル入力
3 5 2
1 5 3 3 3
4 1 3 3 4
4 4 2 4 3

サンプル出力
4 20

データ制約

問題の解決策

左から右へ、幅保持領域Kからスイープ

位置(i、j)が存在する場合は、[I] [j]は[I] [J]に(I、J + 1)〜(I、J + K)を表しBZ得られます

だから、結果に影響を与えない領域に左上の座標点の各点で評価されたとき

したがって、維持するために各値が生じるの列重みが、0 - > 1を直接添加し、1 - > 0 [i]は[J] BZで削除され= 0場合

削除/ときプリ/ポスト追加の値の位置を得るためにのみ必要

セグメントツリーも_Find_nextのビットセットで使用することができます()

しかし、それはNOIP使用すべきではありません

これは、(明確な手書きビットセットです

コード

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define change(T,t) b[T][(t)/64]^=p[(t)%64]
#define pd(T,t) (b[T][(t)/64]&p[(t)%64])
#define min(a,b) (a<b?a:b)
#define max(a,b) (a>b?a:b)
#define low(x) ((x)&-(x))
#define Len 100000
using namespace std;

unsigned long long p[64];
int a[3001][3001];
int f[3002][3001];
bool bz[3001][3001];
int num[100001];
unsigned long long b[200001][47];
char st[72000001];
char *Ch=st;
int N,n,m,K,i,j,k,l;
long long ans1,ans2;

int getint()
{
    int x=0;
    
    while (*Ch<'0' || *Ch>'9') *++Ch;
    while (*Ch>='0' && *Ch<='9') x=x*10+(*Ch-'0'),*++Ch;
    
    return x;
}

int find(int T,int t)
{
    int i,j,s=t/64;t%=64;
    unsigned long long S=b[T][s];
    
    if (t<63)
    S>>=t+1;
    else
    S=0;
    
    if (S)
    return floor(log2(low(S))+0.1)+64*s+t+1;
    
    fo(i,s+1,N)
    if (b[T][i])
    return floor(log2(low(b[T][i]))+0.1)+64*i;
    
    return -1;
}

void add(int I,int i,int j,int s)
{
    int k,l,L,R;
    
    change(a[i][j],i);
    change(a[i][j]+Len,n-i+1);
    
    k=find(a[i][j]+Len,n-i+1);if (k!=-1) k=n-k+1;
    l=find(a[i][j],i);
    
    L=max(i-K+1,1);
    R=i;
    
    if (k!=-1) L=max(L,k+1);
    if (l!=-1) R=min(R,l-K);
    
    if (L<=R)
    f[L][I]+=s,f[R+1][I]-=s;
}

int main()
{
//  freopen("b53.in","r",stdin);
    freopen("b.in","r",stdin);
    freopen("b.out","w",stdout);
    
    fread(st,1,72000001,stdin);
    
    p[0]=1;
    fo(i,1,63)
    p[i]=p[i-1]<<1;
    
    n=getint(),m=getint(),K=getint();N=n/64;
    fo(i,1,n)
    {
        fo(j,1,m)
        a[i][j]=getint();
    }
    
    memset(num,127,sizeof(num));
    
    fo(i,1,n)
    {
        fd(j,m,1)
        {
            bz[i][j]=(num[a[i][j]]-j)<=K;
            num[a[i][j]]=j;
        }
        
        fo(j,1,m)
        num[a[i][j]]=2133333333;
    }
    
    fo(j,1,K)
    {
        fo(i,1,n)
        if (!pd(a[i][j],i))
        add(1,i,j,1);
    }
    fo(j,2,m-K+1)
    {
        fo(i,1,n) 
        f[i][j]=f[i][j-1];
        
        fo(i,1,n)
        {
            if (!pd(a[i][j+K-1],i))
            add(j,i,j+K-1,1);
            if (!bz[i][j-1])
            add(j,i,j-1,-1);
        }
    }
    
    fo(i,1,n-K+1)
    {
        fo(j,1,m-K+1)
        {
            f[i][j]+=f[i-1][j];
            
            ans1=max(ans1,f[i][j]);
            ans2+=f[i][j];
        }
    }
    printf("%lld %lld\n",ans1,ans2);
    
    fclose(stdin);
    fclose(stdout);
    
    return 0;
}

おすすめ

転載: www.cnblogs.com/gmh77/p/11795520.html