NC232413. Painting Fences
描述
输入描述
第一行是三个正整数 。
接下来 行,每行为以下两种:
- `1 x y` 加入限制「 不能是 」。保证这次操作之前, 可以是 。- `2 id` 取消第 个操作的限制(下标从 开始,取消的操作保证是第一种类型的操作)。对于所有数据,,,,保证任意时刻至少有一种合法方案。
输出描述
行,对初始状态、每个操作后的状态分别输出答案对 取模的值。
示例1
输入:
4 2 5 1 2 1 1 1 1 1 3 2 2 2 1 4 2
输出:
499122179 499122179 2 499122179 3 499122179
说明:
- 在所有操作之前的方案:,答案等于 。C++ 解法, 执行用时: 1641ms, 内存消耗: 60956K, 提交时间: 2022-01-20 22:18:59
#include <bits/stdc++.h> using namespace std; typedef long long ll; #define M 998244353 int i,j,k,n,m,t,x,y,ty; int op1[300500],op2[300500]; ll a[300500],b[300500],res; ll ksm(ll a,ll p){ll res=1;while(p){if(p&1){res=res*a%M;}a=a*a%M;p>>=1;}return res;} int su(ll a,ll b){a+=b;return (a>=M)?a-M:a;} map<int,int> mp[300500]; void add(int l,int r,int op){ if(x<1||r>n)return; ll sum=a[l]*a[r]%M,sb; sb=su(sum,M-b[l])*ksm(sum,M-2)%M; res=su(res,(op>0)?sb:M-sb); } int main() { ios::sync_with_stdio(0); cin>>n>>m>>t; for(i=1;i<=n;i++)a[i]=b[i]=m; res=1+1ll*(n-1)*(m-1)%M*ksm(m,M-2)%M; cout<<res<<'\n'; for(int T=1;T<=t;T++){ cin>>ty; if(ty==1){ cin>>x>>y; op1[T]=x;op2[T]=y; add(x-1,x,-1);add(x,x+1,-1); a[x]--;mp[x][y]=1; if(x>1&&!mp[x-1][y]){b[x-1]--;} if(x<n&&!mp[x+1][y]){b[x]--;} add(x-1,x,1);add(x,x+1,1); } else{ cin>>k; x=op1[k];y=op2[k]; add(x-1,x,-1); add(x,x+1,-1); a[x]++;mp[x][y]=0; if(x>1&&!mp[x-1][y])b[x-1]++; if(x<n&&!mp[x+1][y])b[x]++; add(x-1,x,1);add(x,x+1,1); } cout<<res<<'\n'; } }