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;
}
时间: 2024-10-17 20:54:16

ARC 061D すぬけ君の塗り絵 set模拟的相关文章

すぬけ君の塗り絵 / Snuke&#39;s Coloring AtCoder - 2068 (思维,排序,贡献)

Problem Statement We have a grid with H rows and W columns. At first, all cells were painted white. Snuke painted N of these cells. The i-th ( 1≤i≤N ) cell he painted is the cell at the ai-th row and bi-th column. Compute the following: For each inte

csp退役前的做题计划1(真)

csp退役前的做题计划1(真) 因为我太菜了,所以在第一次月考就会退役,还是记录一下每天做了什么题目吧. 任务计划 [ ] Z算法(Z Algorithm) 9.28 [x] ARC061C たくさんの数式 / Many Formulas [x] ARC061D すぬけ君の塗り絵 / Snuke's Coloring [x] ARC061E すぬけ君の地下鉄旅行 / Snuke's Subway Trip [x] ARC061F 3人でカードゲーム / Card Game for Three [

NOIP模拟 B君的数组 题解

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置. %%%%%%%%%%%%%毕克dalao  Orzzzzzzzzzzzz 题目大意: 给出一个数组a,大小是2^k,下标从0开始. 求:对于每个x(0<=x<2^k),下标满足x&i = i的所有ai的和. 输入格式: 第一行有一个整数N,表示数组的大小. 接下来N行,每行一个整数,表示ai. 输出格式: 每行输出一个整数,表示所求答案. 输出共包含N行. 样例输入: 4 1 2 4 8 样例输出: 1 3 5 15

计蒜客模拟赛D1T2 蒜头君的树:树上节点之间最短距离和

题目链接:https://nanti.jisuanke.com/t/16446 题意: 给你一棵有n个节点的树以及每条边的长度,输出树上节点之间的最短距离和.然后进行m次操作,每次操作更改一条边的长度,分别输出每次操作后树上节点之间的最短距离和. 题解: 最短距离和 = ∑(树上每一条边被最短路经过的次数 * 这条边的长度) 一个节点到它父节点的边被经过的次数 = 该节点以及它的子孙的节点个数 * 除了该节点和它子孙之外的所有节点总个数 每一个节点以及它子孙节点的个数总和用一遍dfs保存在num

计蒜客模拟赛D1T1 蒜头君打地鼠:矩阵旋转+二维前缀和

题目链接:https://nanti.jisuanke.com/t/16445 题意: 给你一个n*n大小的01矩阵,和一个k*k大小的锤子,锤子只能斜着砸,问只砸一次最多能砸到多少个1. 题解: 将原矩阵顺时针旋转45°,二维前缀和预处理,然后枚举每一个可能砸到的正方形之和并取最大. 注:枚举的正方形的四个顶点必须是从原矩阵璇转过来的点,代码中用vis数组判断. #include <iostream> #include <stdio.h> #include <string.

noip模拟赛 蒜头君的树

分析:这道题问的是树上整体的答案,当然要从整体上去考虑. 一条边对答案的贡献是这条边一端连接的点的个数*另一端连接的点的个数*边权,可以用一次dfs来统计答案,之后每次更改操作在原答案的基础上增减就好了. 千万不要傻傻地去求LCA......事实证明只有10分.问的是任意两点最短距离之和,树上两个点的最短路径只有一条,所以才要去考虑每条边的贡献的. #include <cstdio> #include <cstring> #include <iostream> #inc

noip模拟赛 蒜头君打地鼠

分析:直接一个一个地去暴力枚举分数比较少,我们需要一种比较快的统计一定空间内1的数量,标准做法是前缀和,但是二维前缀和维护的是一个矩形内的值,这个是旋转过的该怎么办?可以把图旋转45°,不过这样比较考验码力,我们可以考虑维护每一行的前缀和,写得好常数小一点加上读入优化就能A了. #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespa

noip模拟赛 蒜头君的兔子

分析:直接暴力算有30分,像斐波那契那样推式子算有60分,如果想要得到100分就要用一种数列题的常见优化--矩阵了. 当前的兔子数和十年内的兔子数有关,我们需要1个1*11的矩阵,来记录当前为0岁.1岁.2岁......兔子的数量,同时还需要一个快速幂矩阵进行计算.由于一年后a[1] = a[0],a[2] = a[1],......,a[10] = a[9],a[0] = a[1] + a[2] + a[3] + ...... + a[10],很容易构造出矩阵来. 因为矩阵比较复杂,还是推荐用

复习---归并排序求逆序对--计蒜客2017noip模拟赛二--蒜头君的排序

题目链接:https://nanti.jisuanke.com/t/16443 我不会矩阵快速幂,所以只拿了60分, 发现归并排序掌握的并不熟练,借此良机复习一下. 重在归并排序分治思想,要牢记! #include<iostream> #include<cstring> using namespace std; int n,m,a[30005],s[30005],ans,d[30005]; void msort(int l,int r) { if(l==r)return;//如果只