ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

8.4

2022-08-05 14:32:42  阅读:142  来源: 互联网

标签:8.4 int sum ++ -- vector mod


CF1574E

题意:

  • 给一个 \(n \times m\) 的 \(空/0/1\) 矩阵(初始全空)。

  • \(k\) 次操作,每次操作会把一个格子样式修改。

  • 求每次修改后填充剩下空格子的方案数,使所有 \(2 \times 2\) 的子矩阵 \(4\) 个元素之和为 \(2\) (也就是有 \(2\) 个 \(1\) 和 \(2\) 个 \(0\))。

  • \(n,m \leq 10^6,k \leq 3 \times 10^5\),答案对 \(998244353\) 取模。

题解:

考虑所有满足的要求的\(2*2\)的格子:

要么它的两行上的数字相反,要么两列上的数字相反。或者行和列上的数字都相反(\(01\)间隔)

拓展一下,\(n*m\)的满足要求的矩阵,要么每两行之间的数字都是相反,要么每两列的数字都是相反的,或者两者都满足。

那么其实整个网格的填数方案都取决于第一行和第一列的填数方案。

以第一行举例子,当一个位置上的数字确定时,它所对应的行首填的数就确定了。

如果在行上没有冲突,那么方案就是\(2^x\),其中\(x\)是空闲行的数量。

列上同理,不过要容斥掉行和列都满足的情况,也就是所有格子都\(01\)相间的情况。

这种情况最多有两种。

#include<bits/stdc++.h>
using namespace std;
namespace red{
#define int long long
#define double long double
#define ls(p) (p<<1)
#define rs(p) (p<<1|1)
#define lowbit(i) ((i)&(-i))
#define mid ((l+r)>>1)
#define eps (1e-15)
    const int N=2e6+10,mod=998244353,inv2=5e8+4,inf=2e9;
    int fast(int x,int k)
    {
        int ret=1;
        while(k)
        {
            if(k&1) ret=ret*x%mod;
            x=x*x%mod;
            k>>=1;
        }
        return ret;
    }
    inline void main()
    {
        int n,m,k;cin>>n>>m>>k;
        int sum1=n,sum2=m;
        vector a(n+1,vector<int>(2));
        vector b(m+1,vector<int>(2));
        vector<int> d(2);
        int c1=0,c2=0;
        vector<map<int,int>> mp(1000001);
        auto del=[&](int x,int y) -> void
        {
            if(!mp[x][y]) return;
            int c=mp[x][y]-1;mp[x][y]=0;
            if(a[x][(y&1)^c]==1&&a[x][(y&1)^c^1]>0) --c1;
            if(b[y][(x&1)^c]==1&&b[y][(x&1)^c^1]>0) --c2;
            if(a[x][(y&1)^c]==1) ++sum1;
            if(b[y][(x&1)^c]==1) ++sum2;
            --a[x][(y&1)^c];
            --b[y][(x&1)^c];
            --d[((x+y)&1)^c];
        };
        auto add=[&](int x,int y,int c) -> void
        {
            mp[x][y]=c+1;
            if(a[x][(y&1)^c]==0&&a[x][(y&1)^c^1]>0) ++c1;
            if(b[y][(x&1)^c]==0&&b[y][(x&1)^c^1]>0) ++c2;
            if(a[x][(y&1)^c]==0) --sum1;
            if(b[y][(x&1)^c]==0) --sum2;
            ++a[x][(y&1)^c];
            ++b[y][(x&1)^c];
            ++d[((x+y)&1)^c];
        };
        auto query=[&](int x,int y) -> int
        {
            int sum=0;
            if(!c1) sum=(sum+fast(2,sum1));
            if(!c2) sum=(sum+fast(2,sum2));
            if(!d[0]) --sum;
            if(!d[1]) --sum;
            return (sum%mod+mod)%mod;
        };
        for(int i=1;i<=k;++i)
        {
            int x,y,z;cin>>x>>y>>z;
            del(x,y);
            if(z!=-1) add(x,y,z);
            cout<<query(x,y)<<'\n';
        }
    }
}
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    red::main();
    return 0;
}
/*

*/

标签:8.4,int,sum,++,--,vector,mod
来源: https://www.cnblogs.com/knife-rose/p/16554175.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有