首页 > 代码库 > ARC 061D すぬけ君の塗り絵 set模拟

ARC 061D すぬけ君の塗り絵 set模拟

 

题意:H*W矩形 初始全部为白色,n次操作 将某个(a,b)涂黑,问3*3子矩形中,黑色个数为0~9分别有多少个?

H*W<=1e9 n<=1e5.

按矩形的右下角来计数,(每个矩形可以按右下角来编号),填一个格子(a,b)右下角(a+i,b+j),包含它的有9个.

set[i] 记录有多少个矩形被加i次,枚举i,(x,y)找到原来被加的次数 然后更新即可 O(N*100*logn)

直接用map统计也行

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> ii;
const int N=3e2+20;
set<ii> s[N];
int main()
{
    ll h,w,n,a,b;
    while(cin>>h>>w)
    {
        cin>>n;
        for(int i=0;i<=10;i++)
            s[i].clear();
        for(int i=0;i<n;i++)
        {
            scanf("%lld%lld",&a,&b);
            for(int i=0;i<3;i++)
            {
                for(int j=0;j<3;j++)
                {
                    int pos=0;
                    if(a+i>h||b+j>w||a+i<3||b+j<3)
                        continue;
                //    cout<<a+i<<‘ ‘<<b+j<<endl;
                    for(int k=0;k<10;k++)
                    {
                        ii t=ii(a+i,b+j);
                        if(s[k].find(t)!=s[k].end())
                        {
                            pos=k;
                            break;
                        }
                    }
                    if(pos)
                        s[pos].erase(ii(a+i,b+j));
                    s[pos+1].insert(ii(a+i,b+j));
                }
            }    
        }
        ll cnt=0;
        for(int k=1;k<=9;k++)
            cnt+=s[k].size();
        printf("%lld\n",(h-2ll)*(w-2ll)-cnt);
        for(int k=1;k<=9;k++)
            printf("%lld\n",s[k].size());    
    }
    return 0;
}

 

ARC 061D すぬけ君の塗り絵 set模拟