C2

首先用并查集维护\(1\)的连通块,然后用另外一个并查集维护第\(i\)行中,第\(j\)列之后的第一个\(0\)的位置,就是如果当前位置是\(1\)那么它的父亲是它右边的格子,否则是它自己。

时间复杂度\(O(nm\log m+nq)\)。

#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

首先甩上来一个单位根反演。

\[F_n=\frac{1}{2}((b+\sqrt a)^n+(b-\sqrt a)^n)
\]

于是你发现\(p\)不是质数,于是就自闭了。

然后你想起了BJ人民的扩域做法,就是搞一个域\(Z[\sqrt a]=\{x+y\sqrt a|x,y\in Z\}\),然后直接计算快速幂。但是你绝望地发现,最后有一个\(\frac{1}{2}\),于是你又废了。

然后你去看题解,发现逆向思维是非常重要的。平常大家都是递推公式\(\rightarrow\)通项公式,但是你有想到通项公式\(\rightarrow\)递推公式吗?

根据特征方程的理论,设\(F_n=AF_{n-1}+BF_{n-2}\),那么\(x^2-Ax-B=0\)的两根为\(b\pm \sqrt a\),所以\(A=b+\sqrt a+b-\sqrt a=2b\),\(B=-(b+\sqrt a)(b-\sqrt a)=a-b^2\)。然后用矩阵快速幂求出\(F_n\)就可以了。

#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

这是一个看上去很吓人的计算几何。

首先我们发现,这个范围实际上就是两个相距\(2d\)的平行线之间的部分,于是我们枚举其中一个平行线,发现它总能经过一个点,我们枚举这个点\(A\),看它在哪些时候可以覆盖另外一个点\(B\)。

分类讨论。

  1. \(dis(A,B)\le 2d\),设\(\alpha=\arctan\frac{y_B-y_A}{x_B-x_A}\),则直线倾角的范围是\([\alpha,\alpha+\pi]\)

  2. \(dis(A,B)>2d\),设\(\beta=\arcsin\frac{2d}{dis(A,B)}\),则直线倾角的范围是\([\alpha,\alpha+\beta]\cup[\alpha+\pi-\beta,\alpha+\pi]\)

如果看不懂的话,就来看个图。

于是问题就转化成了给出一堆区间,求一个点至多被覆盖多少次。这是一个经典题

#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);
}

Comet OJ Contest #13 简要题解的更多相关文章

  1. Comet OJ - Contest #2 简要题解

    Comet OJ - Contest #2 简要题解 cometoj A 模拟,复杂度是对数级的. code B 易知\(p\in[l,r]\),且最终的利润关于\(p\)的表达式为\(\frac{( ...

  2. Comet OJ - Contest #2简要题解

    Comet OJ - Contest #2简要题解 前言: 我没有小裙子,我太菜了. A 因自过去而至的残响起舞 https://www.cometoj.com/contest/37/problem/ ...

  3. Comet OJ - Contest #5 简要题解

    好久没更博了,还是象征性地更一次. 依然延续了简要题解的风格. 题目链接 https://cometoj.com/contest/46 题解 A. 迫真字符串 记 \(s_i\) 表示数字 \(i\) ...

  4. Comet OJ - Contest #13 「火鼠的皮衣 -不焦躁的内心-」

    来源:Comet OJ - Contest #13 芝士相关: 复平面在信息学奥赛中的应用[雾 其实是道 sb 题??? 发现原式貌似十分可二项式定理,然后发现确实如此 我们把 \(a^i\) 替换成 ...

  5. Comet OJ - Contest #13 「佛御石之钵 -不碎的意志-」(hard)

    来源:Comet OJ - Contest #13 一眼并查集,然后发现这题 tmd 要卡常数的说卧槽... 发现这里又要用并查集跳过访问点,又要用并查集维护联通块,于是开俩并查集分别维护就好了 一开 ...

  6. 【题解】Comet OJ Round 70 简要题解

    [题解]Comet OJ Round 70 简要题解 A 将放在地上的书按照从小到大排序后,问题的本质就变成了合并两个序列使得字典序最小.可以直接模拟归并排序.直接用循环和std::merge实现这个 ...

  7. Comet OJ Contest #13 D

    Comet OJ Contest #13 D \(\displaystyle \sum_{i=0}^{\left\lfloor\frac{n}{2}\right\rfloor} a^{i} b^{n- ...

  8. Comet OJ - Contest #13 「佛御石之钵 -不碎的意志-」(困难版) 并查集

    题意 给一个$ n \times m$ 的网格,每个格子里有一个数字,非 \(0\) 即 \(1\),行从上往下依次编号为 \(1, 2, \cdots, n\),列从左往右依次编号为 \(1, 2, ...

  9. Comet OJ - Contest #13

    Rank53. 第一次打这种比赛.还是有不少问题的,以后改吧. A题WA了两次罚了不少时. C写到一半发现只能过1,就先弃了. D一眼没看出来.第二眼看出来就是一个类似于复数的快速幂. 然后B切了. ...

随机推荐

  1. js调用浏览器复制

    <script type="text/javascript"> function copyUrl2() { var Url2=document.getElementBy ...

  2. 如何在vue项目中引入element-ui

    安装 elementUI npm install element-ui --save 引入elementUI import ElementUI from 'element-ui' import 'el ...

  3. java通过poi读取excel中的日期类型数据或自定义类型日期

    Java 读取Excel表格日期类型数据的时候,读出来的是这样的  12-十月-2019,而Excel中输入的是 2019/10/12 或 2019-10-12 poi处理excel时,当excel没 ...

  4. SIM7600CE http post

    SIM7600CE是一款SMT封装的模块,支持 LTE-TDD/LTE-FDD/HSPA+/TD-SCDMA/EVDO和GSM/GPRS/EDGE等频段,支持LTE CAT4(下行速度为150Mbps ...

  5. (四)react-native开发系列之debug调试

    一个高效率的开发,不仅仅需要扎实的专业,掌握熟练的调试技巧也是必备技能,熟练的调试技能可以加快开发速度和提升代码质量,降低bug量,可以起到事半功倍的效果:今天来说下react-native在开发过程 ...

  6. JS去除字符串左右两端的空格(转载)

    来源:https://www.cnblogs.com/fanyf/p/3785387.html var str='     测试     '; 一.函数 <script type="t ...

  7. Dubbo 高级特性实践-泛化调用

    引言 当后端Java服务用Dubbo协议作为RPC方案的基础,但部分消费方是前端Restful的PHP服务,不能直接调用,于是在中间架设了Router服务提供统一的基于HTTP的后端调用入口. 而Ro ...

  8. MySQL Backup--Xtrabackup备份异常(MySQL Server has gone away)

    错误场景MySQL 版本:5.7.24XtraBackup 版本:2.4.8CentOS 版本:6.5 MySQL需要新增一个从库,为避免XtraBackup备份影响生产,选择在从库上进行备份,备份脚 ...

  9. mysql Starting MySQL..The server quit without updating PID file

    可能的原因和解决办法 1.可能是/usr/local/mysql/data/rekfan.pid文件没有写的权限解决方法 :给予权限,执行 chown -R mysql:mysql /var/data ...

  10. tomcat 使用quercus-4.0.39 支持PHP

    tomcat  使用quercus-4.0.39  支持PHP   Quercus是Caucho公司采用纯Java开发的一个PHP5引擎.基于开源授权协议GPL发布.Quercus自带很多个PHP模块 ...