Submission #539029

#TimeUsernameProblemLanguageResultExecution timeMemory
539029amunduzbaevL-triominoes (CEOI21_ltriominoes)C++17
28 / 100
116 ms6376 KiB
#include "bits/stdc++.h"
using namespace std;

#define ar array

struct mtx{
	vector<vector<int>> t;
	int n;
	
	mtx (int sz){
		n = sz;
		t.resize(n, vector<int>(n, 0));
	}
	
	mtx operator * (mtx& b){
		mtx c(n);
		for(int i=0;i<n;i++){
			for(int j=0;j<n;j++){
				for(int k=0;k<n;k++){
					c.t[i][j] |= (t[i][k] & b.t[k][j]);
				}
			}
		} return c;
	}
};

signed main(){
	ios::sync_with_stdio(0); cin.tie(0);
	
	int n, m, k; cin>>n>>m>>k;
	vector<ar<int, 2>> a(k);
	for(int i=0;i<k;i++){
		cin>>a[i][0]>>a[i][1];
		a[i][0]--, a[i][1]--;
	}
	
	if(n <= 7){
		vector<mtx> pw(30, mtx(1 << n));
		{
			mtx dp(1 << n);
			for(int i=0;i < (1 << n);i++){
				for(int j=0;j < (1 << (n + n));j++){
					int mask = 0, mm = i;
					for(int l=0;l<n;l++){
						if(mm >> l & 1) continue;
						int v = (j >> (2 * l)) & 3;
						if(v == 0){
							if(l + 1 < n && !(mm >> (l + 1) & 1) && !(mask >> (l + 1) & 1)){
								mm |= (1 << l);
								mm |= (1 << (l + 1));
								mask |= (1 << (l + 1));
							}
						}
						if(v == 1){
							if(l + 1 < n && !(mm >> (l + 1) & 1) && !(mask >> l & 1)){
								mm |= (1 << l);
								mm |= (1 << (l + 1));
								mask |= (1 << l);
							}
						}
						if(v == 2){
							if(l && !(mask >> (l - 1) & 1) && !(mask >> l & 1)){
								mm |= (1 << l);
								mask |= (1 << l);
								mask |= (1 << (l - 1));
							}
						}
						if(v == 3){
							if(l + 1 < n && !(mask >> (l + 1) & 1) && !(mask >> l & 1)){
								mm |= (1 << l);
								mask |= (1 << l);
								mask |= (1 << (l + 1));
							}
						}
					}
					
					if(mm == (1 << n) - 1 && !dp.t[i][mask]){
						//~ for(int j=0;j<n;j++) cout<<(i >> j & 1);
						//~ cout<<endl;
						//~ for(int j=0;j<n;j++) cout<<(mask >> j & 1);
						//~ cout<<endl<<endl;
						dp.t[i][mask] = 1;
					}
				}
			}
			
			pw[0] = dp;
			for(int j=1;j<30;j++){
				pw[j] = pw[j-1] * pw[j-1];
			}
		}
		
		sort(a.begin(), a.end(), [&](auto& a, auto& b){
			return (a[1] < b[1]);
		});
		
		vector<int> dp(1 << n);
		dp[(1 << n) - 1] = 1;
		int last = -1;
		for(int i=0;i<k;){
			int j = i, rev = 0;
			while(j<k && a[j][1] == a[i][1]) rev |= (1 << a[j][0]), j++;
			
			int d = a[i][1] - last;
			for(int l=29;~l;l--){
				if(d >> l & 1){
					d ^= (1 << l);
					vector<int> tp(1 << n);
					for(int mask=0;mask < (1 << n);mask++){
						for(int j=0;j < (1 << n);j++){
							if(d){
								tp[j] |= (dp[mask] & pw[l].t[mask][j]);
							} else {
								if(j & rev) continue;
								tp[j | rev] |= (dp[mask] & pw[l].t[mask][j]);
							}
						}
					}
					swap(tp, dp);
				}
			} last = a[i][1], i = j;
		}
		
		int d = m - last - 1;
		for(int l=29;~l;l--){
			if(d >> l & 1){
				vector<int> tp(1 << n);
				for(int mask=0;mask < (1 << n);mask++){
					for(int j=0;j < (1 << n);j++){
						tp[j] |= dp[mask] & pw[l].t[mask][j];
					}
				}
				
				swap(tp, dp);
			}
		}
		
		if(dp[(1 << n) - 1]) cout<<"YES\n";
		else cout<<"NO\n";
	} else {
		vector<vector<mtx>> pw(5, vector<mtx>(30, mtx(0)));
		for(int t=2;t<7;t++){
			int n = t + 1;
			mtx dp(1 << n);
			for(int i=0;i < (1 << n);i++){
				for(int j=0;j < (1 << n);j++){
					int mask = 0, mm = i;
					for(int l=0;l<n;l++){
						if(mm >> l & 1) continue;
						if(l + 1 < n && !(mm >> (l + 1) & 1) && !(mask >> (l + (j >> l & 1)) & 1) && 
						(j >> l & 1) == (j >> (l + 1) & 1)){
							mm |= (1 << l);
							mm |= (1 << (l + 1));
							mask |= (1 << (l + (j >> l & 1)));
						} else if((j >> l & 1) && l + 1 < n && !(mask >> (l + 1) & 1) && !(mask >> l & 1)){
							mm |= (1 << l);
							mask |= (1 << l);
							mask |= (1 << (l + 1));
						} else if(!(j >> l & 1) && l && !(mask >> (l - 1) & 1) && !(mask >> l & 1)){
							mm |= (1 << l);
							mask |= (1 << l);
							mask |= (1 << (l - 1));
						}
					}
					
					if(mm == (1 << n) - 1 && !dp.t[i][mask]){
						//~ for(int j=0;j<n;j++) cout<<(i >> j & 1);
						//~ cout<<endl;
						//~ for(int j=0;j<n;j++) cout<<(mask >> j & 1);
						//~ cout<<endl<<endl;
						dp.t[i][mask] = 1;
					}
				}
			}
			
			pw[t - 2][0] = dp;
			for(int j=1;j<30;j++){
				pw[t - 2][j] = pw[t - 2][j-1] * pw[t - 2][j-1];
			}
		}
		
		sort(a.begin(), a.end(), [&](auto& a, auto& b){
			return (a[1] < b[1]);
		});
		vector<int> dp(1 << n);
		auto solve = [&](int l, int r, vector<int>& t1, int& d, int& I, int rev){
			int t = (r - l);
			vector<int> d1(1 << t);
			for(int mask=0;mask<(1 << n);mask++){
				int m = (mask >> l) & ((1 << t) - 1);
				d1[m] |= dp[mask];
			} rev = (rev >> l) & ((1 << t) - 1);
			
			for(int mask=0;mask < (1 << t);mask++){
				for(int j=0;j < (1 << t);j++){
					if(d){
						t1[j] |= (d1[mask] & pw[t - 3][I].t[mask][j]);
					} else {
						if(rev & j) continue;
						t1[rev | j] |= (d1[mask] & pw[t - 3][I].t[mask][j]);
					}
				}
			}
		};
		
		dp[(1 << n) - 1] = 1;
		int last = -1;
		for(int i=0;i<k;){
			int j = i, rev = 0;
			while(j<k && a[j][1] == a[i][1]) rev |= (1 << a[j][0]), j++;
			
			int d = a[i][1] - last;
			for(int l=29;~l;l--){
				if(d >> l & 1){
					d ^= (1 << l);
					vector<int> tp(1 << n);
					for(int t=3;t<=7;t++){
						int r = n - t;
						if(r > 7) continue;
						
						vector<int> t1(1 << t), t2(1 << r);
						solve(0, t, t1, d, l, rev);
						solve(t, n, t2, d, l, rev);
						for(int mask=0;mask < (1 << n);mask++){
							tp[mask] |= (t1[mask & ((1 << t) -1 )] & t2[mask >> t]);
						}
					}
					swap(tp, dp);
				}
			} last = a[i][1], i = j;
		}
		
		int d = m - last - 1;
		for(int l=29;~l;l--){
			if(d >> l & 1){
				vector<int> tp(1 << n);
				for(int t=3;t<=7;t++){
					int r = n - t;
					if(r > 7) continue;
					
					vector<int> t1(1 << t), t2(1 << r);
					solve(0, t, t1, d, l, 0);
					solve(t, n, t2, d, l, 0);
					for(int mask=0;mask < (1 << n);mask++){
						tp[mask] |= (t1[mask & ((1 << t) -1 )] & t2[mask >> t]);
					}
				}
				swap(tp, dp);
			}
		}
		
		if(dp[(1 << n) - 1]) cout<<"YES\n";
		else cout<<"NO\n";
	}
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...