QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#393698 | #5521. Excellent XOR Problem | evirir | RE | 0ms | 0kb | C++20 | 6.0kb | 2024-04-19 08:41:17 | 2024-04-19 08:41:18 |
answer
#include <bits/stdc++.h>
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
//using namespace __gnu_pbds;
// #pragma GCC optimize("O3,unroll-loops")
// #pragma GCC target("avx2")
#define watch(x) cout<<(#x)<<"="<<(x)<<'\n'
#define mset(d,val) memset(d,val,sizeof(d))
#define cbug if(DEBUG) cout
#define setp(x) cout<<fixed<<setprecision(x)
#define sz(x) (int)(x).size()
#define all(x) begin(x), end(x)
#define forn(i,a,b) for(int i=(a);i<(b);i++)
#define fore(i,a,b) for(int i=(a);i<=(b);i++)
#define pb push_back
#define F first
#define S second
#define fbo find_by_order
#define ook order_of_key
typedef long long ll;
typedef long double ld;
typedef pair<ll,ll> ii;
typedef vector<ll> vi;
typedef vector<ii> vii;
//template<typename T>
//using pbds = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
void SD(int t=0){ cout<<"PASSED "<<t<<endl; }
ostream& operator<<(ostream &out, ii x){ out<<"("<<x.F<<","<<x.S<<")"; return out; }
template<typename T> ostream& operator<<(ostream &out, const vector<T>& v){ for (const auto& x : v) cout << x << ' '; return out; }
template<typename T> void amax(T &a, T b){ a=max(a,b); }
template<typename T> void amin(T &a, T b){ a=min(a,b); }
struct Hash {
static uint64_t splitmix64(uint64_t x) {
// http://xorshift.di.unimi.it/splitmix64.c
x += 0x9e3779b97f4a7c15;
x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
return x ^ (x >> 31);
}
size_t operator()(uint64_t x) const {
static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
return splitmix64(x + FIXED_RANDOM);
}
};
const ll INF = ll(1e18);
const int MOD = 998244353;
const bool DEBUG = 0;
const int MAXN = 100005;
const int LG = 21;
vector<ll> fact,ifact,inv,pow2;
ll add(ll a, ll b, ll m = MOD)
{
a+=b;
if(abs(a)>=m) a%=m;
if(a<0) a+=m;
return a;
}
ll mult(ll a, ll b, ll m = MOD)
{
if(abs(a)>=m) a%=m;
if(abs(b)>=m) b%=m;
a*=b;
if(abs(a)>=m) a%=m;
if(a<0) a+=m;
return a;
}
void radd(ll &a, ll b, ll m = MOD){ a=add(a,b,m); }
void rmult(ll &a, ll b, ll m = MOD){ a=mult(a,b,m); }
ll pw(ll a, ll b, ll m = MOD)
{
assert(b >= 0); // can return 0 if desired
if(abs(a)>=m) a%=m;
if(a==0 && b==0) return 0; // value of 0^0
ll r=1;
while(b){
if(b&1) r=mult(r,a,m);
a=mult(a,a,m);
b>>=1;
}
return r;
}
ll inverse(ll a, ll m = MOD)
{
return pw(a,m-2);
}
ll choose(ll a, ll b)
{
if(a<b) return 0;
if(b==0) return 1;
if(a==b) return 1;
return mult(fact[a],mult(ifact[b],ifact[a-b]));
}
void init(ll _n)
{
fact.clear(); ifact.clear(); inv.clear(); pow2.clear();
fact.resize(_n+1); ifact.resize(_n+1); inv.resize(_n+1); pow2.resize(_n+1);
pow2[0]=1; ifact[0]=1; fact[0]=1;
for(int i=1;i<=_n;i++){
pow2[i]=add(pow2[i-1],pow2[i-1]);
fact[i]=mult(fact[i-1],i);
}
ifact[_n] = inverse(fact[_n]);
for(int i=_n-1;i>=1;i--){
ifact[i] = mult(ifact[i+1], i+1);
}
for(int i=1;i<=_n;i++){
inv[i] = mult(fact[i-1], ifact[i]);
}
}
void solve()
{
int n,m; cin>>n>>m;
vector<vector<int>> a(n, vector<int>(m));
forn(i,0,n) forn(j,0,m)
{
cin>>a[i][j];
if (a[i][j] != -1) a[i][j]--;
}
forn(i,0,n) forn(j,0,m)
{
if (a[i][j] == -1) continue;
if (a[i][j] < i + j || a[i][j] > i + j + 1)
{
cout << 0 << '\n';
return;
}
}
vector<vector<int>> b(n, vector<int>(m));
forn(i,0,n)
{
forn(j,0,m)
{
if (a[i][j] == -1) b[i][j] = -1;
else if (a[i][j] == i + j + 1) b[i][j] = 1;
else b[i][j] = 0;
}
}
vector<int> l(n, m);
forn(i,0,n)
{
forn(j,0,m)
{
if (b[i][j] == 1)
{
l[i] = j;
break;
}
}
}
forn(i,0,n)
{
if (l[i] == m) continue;
forn(j,l[i],m)
{
if (b[i][j] == 0)
{
cout << 0 << '\n';
return;
}
}
}
{
vector<int> ls;
forn(i,0,n)
{
if (l[i] == m) continue;
ls.pb(l[i]);
}
forn(i,1,sz(ls))
{
if (ls[i] > ls[i - 1])
{
cout << 0 << '\n';
return;
}
}
}
forn(i,0,n)
{
bool found = 0;
forn(j,0,m)
{
found |= b[i][j] == 1;
if (found) b[i][j] = 1;
}
found = 0;
for(int j = m - 1; j >= 0; j--)
{
found |= b[i][j] == 0;
if (found) b[i][j] = 0;
}
}
vector<int> r(n, -1); // rightmost 0, (min left idx on row i) - 1
forn(i,0,n)
{
for (int j = m - 1; j >= 0; j--)
{
if (b[i][j] == 0)
{
r[i] = j;
break;
}
}
}
vector<vector<ll>> dp(n, vector<ll>(m + 1));
vector<vector<ll>> suf(n, vector<ll>(m + 1));
fore(j, r[0] + 1, l[0]) dp[0][j] = 1;
for (int j = m; j >= 0; j--)
{
suf[0][j] = dp[0][j];
if (j < m) radd(suf[0][j], suf[0][j + 1]);
}
forn(i, 1, n)
{
for (int j = l[i]; j > r[i]; j--) dp[i][j] = suf[i - 1][j];
for (int j = m; j >= 0; j--)
{
suf[i][j] = dp[i][j];
if (j + 1 <= m) radd(suf[i][j], suf[i][j + 1]);
}
}
ll ans = 0;
fore(j,0,m) radd(ans, dp[n-1][j]);
cout << ans << '\n';
// cout<<"dp: \n";
// forn(i,0,n) cout<<dp[i]<<'\n';
// cout<<"b: \n";
// forn(i,0,n) cout<<b[i]<<'\n';
// cout<<"l: "<<l<<'\n';
// cout<<"r: "<<r<<'\n';
}
int main()
{
cin.tie(0)->sync_with_stdio(0);
int t; cin>>t;
fore(i,1,t) solve();
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 0
Runtime Error
input:
4 2 0 0 3 1 2 3 5 16 8 4 2 1 6 42 42 42 42 42 42