C2
First with disjoint-set maintenance \ (1 \) communication block, and then another set of check and maintenance of (I \) \ row, the first \ (J \) after the first column \ (0 \) of position, that is, if the current location is \ (1 \) then its father was a grid to its right, or is it your own.
Time complexity \ (O (nm \ NQ + log m) \) .
#include<bits/stdc++.h>
#define Rint register int
using namespace std;
const int N = 1003, d[2][4] = {{0, 1, 0, -1}, {1, 0, -1, 0}};
int n, m, q, fa[N][N], cnt, Fa[N * N], Siz[N * N];
char str[N];
bool a[N][N];
inline int getfa(int x, int y){
return (fa[x][y] == y) ? y : (fa[x][y] = getfa(x, fa[x][y]));
}
inline int Getfa(int x){
return (Fa[x] == x) ? x : (Fa[x] = Getfa(Fa[x]));
}
inline int id(int x, int y){return (x - 1) * m + y;}
inline void work(int x, int y){
for(Rint i = 0;i < 4;i ++){
int nx = x + d[0][i], ny = y + d[1][i];
if(nx >= 1 && nx <= n && ny >= 1 && ny <= m && a[nx][ny]){
int fa1 = Getfa(id(x, y)), fa2 = Getfa(id(nx, ny));
if(fa1 != fa2){
if(Siz[fa1] > Siz[fa2]) swap(fa1, fa2);
Fa[fa1] = fa2; Siz[fa2] += Siz[fa1]; -- cnt;
}
}
}
}
int main(){
scanf("%d%d", &n, &m);
for(Rint i = 1;i <= n * m;i ++) Fa[i] = i, Siz[i] = 1;
for(Rint i = 1;i <= n;i ++){
scanf("%s", str + 1);
for(Rint j = 1;j <= m;j ++){
a[i][j] = (str[j] == '1'); fa[i][j] = j + a[i][j]; cnt += a[i][j];
}
fa[i][m + 1] = m + 1;
}
for(Rint i = 1;i <= n;i ++)
for(Rint j = 1;j <= m;j ++)
if(a[i][j]) work(i, j);
scanf("%d", &q);
while(q --){
int x1, y1, x2, y2;
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
for(Rint i = x1;i <= x2;i ++){
int j = y1;
while((j = getfa(i, j)) <= y2){
++ cnt; a[i][j] = 1; fa[i][j] = j + 1;
work(i, j);
}
}
printf("%d\n", cnt);
}
}
D
First of all thrown up a unit root inversion.
\ [F_n = \ frac {1
} {2} ((b + \ sqrt a) ^ n + (b- \ sqrt a) ^ n) \] Then you find \ (P \) is not a prime number, then it is self-closing a.
Then you think of the extension field practice BJ people, is to engage in a domain \ (the Z-[\ sqrt A] = \ {the X-+ the y-\ sqrt A | the X-, the y-\ in the Z-\} \) , and then directly calculate fast power. But you desperate to find, finally there is a \ (\ FRAC {1} {2} \) , and then you scrap it.
Then you see the solution to a problem, find reverse thinking is very important. Usually we are all recursive formula \ (\ rightarrow \) general term formula, but have you thought of general term formula \ (\ rightarrow \) recurrence formula it?
According to the theory of the characteristic equation set \ (F_n AF_ = {} +. 1-n-n-BF_-2} {\) , then \ (x ^ 2-Ax- B = 0 \) is two to \ (b \ pm \ sqrt A \) , so \ (A = B + \ sqrt A + B- \ sqrt A = 2B \) , \ (B = - (B + \ sqrt A) (B- \ sqrt A) = ab & ^ 2 \) . Then quickly obtained by matrix powers \ (F_n \) on it.
#include<bits/stdc++.h>
#define Rint register int
using namespace std;
typedef long long LL;
int T;
LL a, b, p, n;
inline void upd(LL &a, LL b){a += b; if(a >= p) a -= p;}
struct Matrix {
LL x[2][2];
inline Matrix(){memset(x, 0, sizeof x);}
inline Matrix operator = (const Matrix &o){
memcpy(x, o.x, sizeof x);
return *this;
}
inline Matrix operator * (const Matrix &o) const {
Matrix res;
for(Rint i = 0;i < 2;i ++)
for(Rint k = 0;k < 2;k ++)
for(Rint j = 0;j < 2;j ++)
upd(res.x[i][j], (__int128) x[i][k] * o.x[k][j] % p);
return res;
}
} A, B;
inline Matrix kasumi(Matrix A, LL b){
Matrix res; res.x[0][0] = res.x[1][1] = 1;
while(b){
if(b & 1) res = res * A;
A = A * A; b >>= 1;
}
return res;
}
int main(){
scanf("%d", &T);
while(T --){
scanf("%lld%lld%lld%lld", &n, &a, &b, &p); a %= p; b %= p;
if(n == 0){puts("1"); continue;}
if(n == 1){printf("%lld\n", b); continue;}
A.x[0][0] = 2 * b % p; A.x[0][1] = (a + p - (__int128) b * b % p) % p;
A.x[1][0] = 1; B.x[0][0] = b; B.x[1][0] = 1;
B = kasumi(A, n - 1) * B;
printf("%lld\n", B.x[0][0]);
}
}
E
This is a very scary look of computational geometry.
First, we found that this range is in fact two spaced \ (2D \) portion between the parallel lines, so we enumerate wherein a parallel line, it always found through a point, this point we enumerate \ (A \) , to see what it can cover at a further time point \ (B \) .
Category talk.
\ (DIS (A, B) \ Le 2D \) , provided \ (\ Alpha = \ arctan \ FRAC {y_B-Y_A} {x_b-X_a} \) , the angle range in which linearity is \ ([\ alpha, \ alpha + \ pi] \)
\ (DIS (A, B)> 2D \) , provided \ (\ Beta = \ arcsin \ FRAC {2D} {DIS (A, B)} \) , the angle range in which linearity is \ ([\ alpha, \ alpha + \ beta] \ cup [ \ alpha + \ pi- \ beta, \ alpha + \ pi] \)
If you do not understand the words, they look at a map.
The question then transformed into a pile given range, find a point is covered up many times. This is a classic problem
#include<bits/stdc++.h>
#define Rint register int
using namespace std;
const int N = 16003;
const double PI = acos(-1);
int n, d, x[N], y[N], ans, tag[N], len, tot;
double l[N], r[N], val[N];
inline void add(double x, double y){
if(x < 0 && y < 0) x += PI * 2, y += PI * 2;
if(x < 0){
l[++ tot] = x + 2 * PI; r[tot] = 2 * PI; val[++ len] = x + 2 * PI; val[++ len] = 2 * PI;
l[++ tot] = 0; r[tot] = y; val[++ len] = 0; val[++ len] = y;
} else {
l[++ tot] = x; r[tot] = y; val[++ len] = x; val[++ len] = y;
}
}
inline void work(int p){
len = tot = 0;
for(Rint i = 1;i <= n;i ++) if(i != p){
double alpha = atan2(y[i] - y[p], x[i] - x[p]), dis = (x[i] - x[p]) * (x[i] - x[p]) + (y[i] - y[p]) * (y[i] - y[p]);
if(dis <= d * d){
add(alpha, alpha + PI);
} else {
double beta = asin(1.0 * d / sqrt(dis));
add(alpha, alpha + beta); add(alpha + PI - beta, alpha + PI);
}
}
sort(val + 1, val + len + 1);
len = unique(val + 1, val + len + 1) - val - 1;
for(Rint i = 1;i <= tot;i ++){
int a = lower_bound(val + 1, val + len + 1, l[i]) - val, b = lower_bound(val + 1, val + len + 1, r[i]) - val + 1;
++ tag[a]; -- tag[b];
}
for(Rint i = 1;i <= len;i ++){
ans = max(ans, tag[i] += tag[i - 1]); tag[i - 1] = 0;
} tag[len] = 0;
}
int main(){
scanf("%d%d", &n, &d); d <<= 1;
for(Rint i = 1;i <= n;i ++) scanf("%d%d", x + i, y + i);
for(Rint i = 1;i <= n;i ++) work(i);
printf("%d", ans + 1);
}