This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#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 time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |