Submission #170930

#TimeUsernameProblemLanguageResultExecution timeMemory
170930SpeedOfMagicMeksikanac (COCI16_meksikanac)C++17
10 / 160
1550 ms20220 KiB
#include <bits/stdc++.h> using namespace std; template<typename T> using v = vector<T>; //#define int long long typedef long double ld; typedef long long ll; typedef string str; typedef vector<int> vint; #define rep(a, l, r) for(int a = (l); a < (r); a++) #define pb push_back #define fs first #define sc second #define sz(a) ((int) a.size()) const long long inf = 1'000'000'000'000'000'000; const long double EPS = 1e-10; #if 0 //FileIO const string fileName = ""; ifstream fin ((fileName == "" ? "input.txt" : fileName + ".in" )); ofstream fout((fileName == "" ? "output.txt" : fileName + ".out")); #define get fin >> #define put fout << #else #define get cin >> #define put cout << #endif #define eol put endl void read() {} template<typename A,typename... As> void read (A& a,As&... as){get (a) ;read(as...) ;} void print(){} template<typename A,typename... As> void print(A a,As... as){put (a)<<" ";print(as...);} int getInt() { int a; get a; return a; } mt19937 rng{random_device{}()}; void run(); signed main() { ios::sync_with_stdio(0); cin.tie(0); put fixed << setprecision(13); run(); } //code starts here typedef complex<double> base; const double PI = acos(-1.0); void fft (vector<base> & a, bool invert) { int n = (int) a.size(); for (int i=1, j=0; i<n; ++i) { int bit = n >> 1; for (; j>=bit; bit>>=1) j -= bit; j += bit; if (i < j) swap (a[i], a[j]); } for (int len=2; len<=n; len<<=1) { double ang = 2*PI/len * (invert ? -1 : 1); base wlen (cos(ang), sin(ang)); for (int i=0; i<n; i+=len) { base w (1); for (int j=0; j<len/2; ++j) { base u = a[i+j], v = a[i+j+len/2] * w; a[i+j] = u + v; a[i+j+len/2] = u - v; w *= wlen; } } } if (invert) for (int i=0; i<n; ++i) a[i] /= n; } void multiply (const vector<int> & a, const vector<int> & b, vector<int> & res) { vector<base> fa (a.begin(), a.end()), fb (b.begin(), b.end()); size_t n = 1; while (n < max (a.size(), b.size())) n <<= 1; n <<= 1; fa.resize (n), fb.resize (n); fft (fa, false), fft (fb, false); for (size_t i=0; i<n; ++i) fa[i] *= fb[i]; fft (fa, true); res.resize (n); for (size_t i=0; i<n; ++i) res[i] = (int) (fa[i].real() + 0.5); } // (s1 <-) * (s2 ->) and 0s are required struct pt { int x, y; pt() = default; pt(int _x, int _y) : x(_x), y(_y) {} pt(pt a, pt b) : x(b.x - a.x), y(b.y - a.y) {} pt operator-(pt o) const { return { x - o.x, y - o.y }; } int operator*(pt o) const { return x * o.x + y * o.y; } int operator%(pt o) const { return x * o.y - y * o.x; } }; int sgn(int a) { return (0 < a) - (a < 0); } bool belongs(pt a, pt b, pt p) { return ((a - p) * (b - p) <= 0 && (a - p) % (b - p) == 0); } bool segSeg(pt a, pt b, pt c, pt d) { if (belongs(a, b, c) || belongs(a, b, d) || belongs(c, d, a) || belongs(c, d, b)) return 1; pt ab = { a, b }, bc = { b, c }, bd = { b, d }, da = { d, a }, db = { d, b }, cd = { c, d }; return (sgn(ab % bc) != sgn(ab % bd) && sgn(cd % da) != sgn(cd % db)); } bool in(vector<pt> pol, pt p) { //uses belongs, segSeg int n = int(pol.size()); int cnt = 0; for (int i = 0; i < n - 1; i++) { pt a = pol[i], b = pol[i + 1]; if (a.y > b.y) swap(a, b); if (belongs(a, b, p)) return true; else if (a.y == p.y) continue; else if (segSeg(a, b, p, { 10000, p.y })) cnt++; } return cnt % 2; } void run() { int n, m; read(m, n); n++; m++; int k; get k; v<pt> flies(k); int K = k; rep(i, 0, k) { read(flies[i].x, flies[i].y); } get k; v<pt> pol(k + 1); int mnX = m, mnY = n; rep(i, 0, k) { read(pol[i].x, pol[i].y); mnX = min(mnX, pol[i].x); mnY = min(mnY, pol[i].y); } pol[k] = pol[0]; int lenC = 0, lenR = 0; rep(i, 0, k + 1) { pol[i].x -= mnX; pol[i].y -= mnY; lenC = max(lenC, pol[i].x); lenR = max(lenR, pol[i].y); } int prn = n, prm = m; if (lenC + 1 > prm || lenR + 1 > prn) { put 0; return; } m += lenC; n += lenR; vint bitsFlies(n * m, 0); rep(i, 0, K) bitsFlies[flies[i].y * m + flies[i].x] = 1; char inPol[lenC + 1][lenR + 1]; for (int py = 0; py < lenR + 1; ++py) for (int px = 0; px < lenC + 1; ++px) inPol[px][py] = in(pol, {px, py}); //eol; rep(i, 0, lenR + 1) { rep(j, 0, lenC + 1) put intersectAfter[j][i]; eol; } eol; // for (int i = lenR; i >= 0; --i) { rep(j, 0, lenC + 1) put char(inPol[j][i] + '0'); eol; } vint bitsPolygon; for (int x = lenC; x >= 0; --x) bitsPolygon.pb(inPol[x][lenR]); for (int y = lenR - 1; y >= 0; --y) { /* rep(x, 0, lenC + 1) bitsPolygon.pb(inPol[x][y]); rep(x, lenC + 1, m) bitsPolygon.pb(0); */ for (int x = m - 1; x >= lenC + 1; --x) bitsPolygon.pb(0); for (int x = lenC; x >= 0; --x) bitsPolygon.pb(inPol[x][y]); } // cerr << "Length of polygon: lenR = " << lenR << ", lenC = " << lenC << endl; vint res; multiply(bitsFlies, bitsPolygon, res); // rep(i, 0, n * m) put bitsFlies[i]; eol; // rep(i, 0, sz(bitsPolygon)) put bitsPolygon[i]; eol; // rep(i, 0, sz(res)) put res[i]; eol; // cerr << sz(bitsFlies) << " " << sz(bitsPolygon) << " " << sz(res) << endl; int ans = 0; vint posPlace; rep(i, 0, n) rep(j, 0, m) posPlace.pb(i < prn && j < prm && i - lenR >= 0 && j - lenC >= 0); // for (int i : posPlace) put i; eol; rep(i, 0, sz(posPlace)) ans += posPlace[i] * (res[i] == 0); put ans; }
#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...
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...