考前

mtr 中午拿着笔记本改题(Orz),一点多发现 13.50 有比赛(截止 12 点都没放出来),赶紧睡。13.40 到了学校,巨瞌睡,洗了把脸到机房发现推迟到 14.30 了,wcnm

趴在桌上睡觉,Orz 抓紧时间打 luogu 月赛的大佬

考场

T1 集体讨论得 dead line 是直线,感觉有点像《仪仗队》,打出 \(n,m\le3\) 的表发现似乎可以枚举以形成直线的两点为对角的矩形算,跳了

T2 想到了正确性不明 \(O(n\log^2 n)\) 点分治,但本人分治学的很烂就没准备写(ys 巨佬考场就写了出来,切了),想到了从大到小加点,并查集维护直径,但不知道如果直径不过当前点怎么办,跳了跳了

T3 一眼线段树求没有花精的区间中最长的,稍微划拉了一下如何 up,感觉可做,毕竟数据结构算是我的强项

怕 T3 写不完,15.20 就开始写了。

回来看 T1,先写完了假做法,发现在 \(3\times4\) 的时候就挂了,看上去要容斥。又开始尝试每次以最下、最右的点为一个端点,用欧拉函数算贡献,然后把这些点去掉,但想不清楚,最后写了暴力跑路

T2 裸暴力

大概 16.00 开始写 T3,先手推清楚了具体如何 up,问题是在线段树的每个节点上开了个结构体(重载小于号),常数巨大。17.00 写完,调了调边界就过了小样例,发现就这个题没大样例。。。只能对拍。结果没拍几组就挂了。慌得一比,调小数据发现比较区间哪个优是不能直接比区间中点到两边的距离,因为 \(0,n+1\) 两个位置上没有花精,改了改重载小于号终于在 17.20 过拍了。。。

交题时怕 T1 MLE,\(N\) 从 \(2\times10^7\) 改到了 \(40^4\)。最后又觉得能多骗分,想着平时能开 \(5\times10^7\) 个 int,于是开到了 \(10^7\)

res

rk1 0+55+100

T1 MLE。平时能恰好开 \(6\times10^7\) 个 int 是因为有 256M,但这题只有 128M。。。

T2 卡常过了一些点

rk2 赵旭兵 60+30+60

rk6 ys 0+100+0

夜莺与玫瑰

枚举方向向量 \((i,j)\),显然有 \(\gcd(i,j)=1\),设这条直线与给定矩形的点的交点为 \((x,y)\),那就统计满足 \((x-i,y-j)\) 在矩形内,\((x+i,y+j)\) 不在矩形内的 \((x,y)\)(即 \((x,y)\) 是这条直线与矩形的最后一个交点,下图中蓝色)。不难算出答案为:

\[\sum_{i=1}^{n-1}\sum_{j=1}^{m-1}[\gcd(i,j)=1](n-i)(m-j)-\max(n-2i,0)\times\max(m-2j,0)
\]
\[=\sum_{i=1}^{n-1}\sum_{j=1}^{m-1}[\gcd(i,j)=1](nm-im-jn+ij)+\sum_{i=1}^{n/2}\sum_{j=1}^{m/2}[\gcd(i,j)=1](-nm+2im+2jn-4ij)
\]

理解:

首先 \(i,j\) 要互质,其次 \((x-i,y-j)\) 在矩形内的 \((x,y)\) 有 \((n-i)(m-j)\) 个(黄色+蓝色),\((x+i,y+j)\) 也在矩形内的有 \((n-2i)(m-2j)\) 个(黄色),容斥一下即可。



由于 \(n\le4000\),可以二维前缀和预处理答案。一个问题是需要卡空间,一个大问题是数据中有 \(n,m=4001\) 的点,出题人我问候你。

基于这个相同的式子,有时间 \(O(n^2+Tn)\),空间 \(O(n^2)\) 的做法

基于莫比乌斯反演,有时间 \(O(n+Tn)\),空间 \(O(n)\) 的做法。

code
#define int unsigned
const int N = 4004, mod = (1<<30)-1;
int T,n,m; int ans[N+8][N+8],a[N+8][N+8];
bitset<N+8> is[N+8]; signed main() {
// freopen("a.in","r",stdin);
// freopen("a.out","w",stdout);
is[1][0] = 1;
For(i,1,N) For(j,1,N) is[i][j] = is[min(i,j)][max(i,j)%min(i,j)];
////////// nm项 ij项
For(i,1,N-1) For(j,1,N-1) if( is[i][j] ) {
++ans[i+1][j+1], a[i+1][j+1] += i*j;
if( i < 2e3+2 && j < 2e3+2 )
--ans[i<<1|1][j<<1|1], a[i<<1|1][j<<1|1] -= 4*i*j;
}
For(i,1,N) For(j,1,N)
ans[i][j] += ans[i-1][j] + ans[i][j-1] - ans[i-1][j-1],
a[i][j] += a[i-1][j] + a[i][j-1] - a [i-1][j-1];
// ans[n][m]: gcd(1..n,1..m)=1的个数(nm项的系数)
// a[n][m]: ij项
For(i,1,N) For(j,1,N) ans[i][j] = ans[i][j]*i*j + a[i][j];
////////// im项 jn项
memset(a,0,sizeof a);
For(i,1,N-1) For(j,1,N-1) if( is[i][j] ) {
a[i+1][j+1] -= i;
if( i < 2e3+2 && j < 2e3+2 ) a[i<<1|1][j<<1|1] += i<<1;
}
For(i,1,N) For(j,1,N)
a[i][j] += a[i-1][j] + a[i][j-1] - a[i-1][j-1],
// a[n][m]: i in [1,n],j in [1,m],gcd(i,j)=1的i的和
ans[i][j] += j*a[i][j]; // 此处的j为式子中的m
memset(a,0,sizeof a);
For(i,1,N-1) For(j,1,N-1) if( is[i][j] ) {
a[i+1][j+1] -= j;
if( i < 2e3+2 && j < 2e3+2 ) a[i<<1|1][j<<1|1] += j<<1;
}
For(i,1,N) For(j,1,N)
a[i][j] += a[i-1][j] + a[i][j-1] - a[i-1][j-1],
ans[i][j] += i*a[i][j];
read(T);
while( T-- ) {
read(n,m);
// assert(n<=4000),assert(m<=4000);
write((n+m+2*ans[n][m])&mod);
}
return ioclear();
}

影子

考场上其实想的差不多

每次合并完并查集后,用当前点点权乘上直径更新答案即可。因为是用当前点来合并连通块,因此如果直径的两个端点在原来的联通块中,那么这次的答案一定不比那时算出来的优(点权不会变大);否则直径一定会过当前点

code
const int N = 1e5+5;
int T,n,mm,val[N],head[N];
struct Edge { int to,w,nxt; } e[N*2]; int id[N];
struct DSU {
int fa,p,q;
LL d;
} s[N]; namespace dist {
int fa[N],dep[N],siz[N],son[N],top[N];
LL d[N];
void dfs1(int u,int f) {
dep[u] = dep[ fa[u]=f ]+1, siz[u] = 1, son[u] = 0;
for(int i = head[u], v; i; i = e[i].nxt) if( (v=e[i].to) != f ) {
d[v] = d[u] + e[i].w;
dfs1(v,u);
siz[u] += siz[v];
if( siz[v] > siz[son[u]] ) son[u] = v;
}
}
void dfs2(int u,int t) {
top[u] = t;
if( son[u] ) dfs2(son[u],t);
for(int i = head[u], v; i; i = e[i].nxt)
if( (v=e[i].to) != fa[u] && v != son[u] ) dfs2(v,v);
}
void init() { dfs1(1,0), dfs2(1,1); }
int lca(int u,int v) {
while( top[u] != top[v] ) {
if( dep[top[u]] < dep[top[v]] ) swap(u,v);
u = fa[top[u]];
}
return dep[u]<dep[v] ? u : v;
}
LL dis(int u,int v) { return d[u]+d[v]-d[lca(u,v)]*2; }
}
using dist::dis; int find(int x) { return s[x].fa==x ? x : s[x].fa=find(s[x].fa); }
void up(int x,int p,int q) {
LL d = dis(p,q);
if( d > s[x].d ) s[x].p = p, s[x].q = q, s[x].d = d;
}
void merge(int x,int y) {
if( x == y ) return;
s[y].fa = x;
int p = s[x].p, q = s[x].q;
up(x,s[y].p,s[y].q);
up(x,p,s[y].p), up(x,p,s[y].q), up(x,q,s[y].p), up(x,q,s[y].q);
} void solve() {
LL ans = 0;
read(n);
For(i,1,n) read(val[i]), id[i] = i, s[i] = (DSU){i,i,i,0};
for(int i = 1; i < n; ++i) {
int x,y,z; read(x,y,z);
e[++mm] = (Edge){y,z,head[x]}, head[x] = mm;
e[++mm] = (Edge){x,z,head[y]}, head[y] = mm;
}
dist::init();
sort(id+1,id+n+1,[](const int &x,const int &y){return val[x]>val[y];});
For(i,1,n) {
int u = id[i];
for(int j = head[u], v; j; j = e[j].nxt)
if( val[ v=e[j].to ] >= val[u] ) merge(find(u),find(v));
ans = max(ans,val[u]*s[find(u)].d);
}
write(ans,10);
} signed main() {
read(T);
while( T-- ) {
mm = 1;
mem(head,0,n);
solve();
}
return ioclear();
}

点分治做法(虽然时间、代码复杂度被爆踩)

玫瑰花精

线段树

考场 code
const int N = 2e5+5, M = 1e6+5;
int n,m; int pos[M];
struct Seg {
int l,r;
int len() {
if( l == 1 ) return r;
if( r == n ) return n-l+1;
return (l+r>>1)-l+1;
}
Seg(int l=0,int r=0):l(l),r(r){}
};
bool operator < (Seg x,Seg y)
{ return x.len()!=y.len() ? x.len()>y.len() : x.l<y.l; } struct Node {
int l,r,lr,rl;
// lr: 从左往右最后一个没占的地方
Seg a;
} t[N*4];
void up(int u) {
int ls = u<<1, rs = u<<1|1;
if( t[ls].lr == t[ls].r && t[rs].lr ) t[u].lr = t[rs].lr;
else t[u].lr = t[ls].lr;
if( t[rs].rl == t[rs].l && t[ls].rl <= n ) t[u].rl = t[ls].rl;
else t[u].rl = t[rs].rl;
t[u].a = min(t[ls].a,t[rs].a);
t[u].a = min(t[u].a,Seg(min(t[ls].rl,t[rs].l),max(t[rs].lr,t[ls].r)));
}
void build(int u,int l,int r) {
t[u].l = l, t[u].r = r;
if( l == r ) {
t[u].lr = t[u].rl = l;
t[u].a = Seg(l,l);
return;
}
int mid = l+r>>1;
build(u<<1,l,mid), build(u<<1|1,mid+1,r);
up(u);
// printf("> %d %d: %d %d %d %d\n",l,r,t[u].lr,t[u].rl,t[u].a.l,t[u].a.r);
}
void modify(int u,int p,bool x) {
if( t[u].l == t[u].r ) {
if( x ) t[u].lr = 0, t[u].rl = n+1, t[u].a = Seg(n+1,0);
else t[u].lr = t[u].rl = t[u].l, t[u].a = Seg(t[u].l,t[u].l);
return;
}
int ls = u<<1, rs = ls|1;
modify( p<=t[ls].r?ls:rs ,p,x);
up(u);
} signed main() {
// freopen("c.in","r",stdin);
// freopen("c.out","w",stdout);
read(n,m);
build(1,1,n);
while( m-- ) {
int op,x; read(op,x);
if( op == 1 ) {
Seg a = t[1].a;
if( a.l == 1 ) pos[x] = 1;
else if( a.r == n ) pos[x] = n;
else pos[x] = a.l+a.r>>1;
modify(1,pos[x],1);
write(pos[x]), putc(10);
} else modify(1,pos[x],0);
}
return ioclear();
}

20210714 noip15的更多相关文章

  1. [Luogu 2678] noip15 子串

    [Luogu 2678] noip15 子串 题目描述 有两个仅包含小写英文字母的字符串 A 和 B.现在要从字符串 A 中取出 k 个互不重叠的非空子串,然后把这 k 个子串按照其在字符串 A 中出 ...

  2. noip15

    童话故事专场 T1 首先,dead line 是一条直线,而不是线段.考试的时候一直以为是线段,那么横竖共有n+m条,考虑斜着的,斜着的交点为有穷的,则需要满足斜率不同,那么只需要统计一边的,再乘2就 ...

  3. 调用免费API查询全年工作日、周末、法定节假日、节假日调休补班数据

    前言 日常开发中,难免会用到判断今天是工作日.周末.法定节假日.节假日调休补班做一些业务处理,例如:仅在上班时间给用户推送消息.本文记录调用免费API查询全年工作日.周末.法定节假日.节假日调休补班数 ...

  4. B 站崩了,总结下「高可用」和「异地多活」

    你好,我是悟空. 一.背景 不用想象一种异常场景了,这就真实发生了:B 站晚上 11 点突然挂了,网站主页直接报 404. 手机 APP 端数据加载不出来. 23:30 分,B 站做了降级页面,将 4 ...

  5. 备战-Java 基础

    备战-Java 基础 仰天大笑出门去,我辈岂是蓬蒿人. 简介:备战-Java 基础. 一.基本数据类型 1.Java基本数据类型 基本数据类型有8种:byte.short.int.long.float ...

  6. 关于Hadoop调优

    Hadoop生产调优 一.HDFS-核心参数 1.NameNode 内存生产配置 1) NameNode 内存计算 每个文件块大概占用 150byte,一台服务器 128G 内存为例,能存储多少文件块 ...

  7. webpack 快速入门 系列 —— 性能

    其他章节请看: webpack 快速入门 系列 性能 本篇主要介绍 webpack 中的一些常用性能,包括热模块替换.source map.oneOf.缓存.tree shaking.代码分割.懒加载 ...

  8. Java 中节省 90% 时间的常用的工具类

    前言 你们有木有喜欢看代码的领导啊,我的领导就喜欢看我写的代码,有事没事就喜欢跟我探讨怎么写才最好,哈哈哈...挺好. 今天我们就一起来看看可以节省 90% 的加班时间的第三方开源库吧,第一个介绍的必 ...

  9. Java基础——逻辑运算符、位运算符

    逻辑运算符.位运算符.三元运算符 逻辑运算符  public class Demon05 {     public static void main(String[] args) {          ...

随机推荐

  1. wdlinux一键安装包

    下载安装(ssh登录服务器,执行如下操作即可,需要用到root用户权限来安装) v3版本已经发布,更多可看论坛 wdCP v3版本讨论区 更多安装请看 http://www.wdlinux.cn/bb ...

  2. 打开随身U盘_办公专用盘 2019年11月29日

    ;;; ; 打开随身U盘_办公专用盘 2019年11月29日 ; https://www.autoahk.com/?p=16553; https://www.cnblogs.com/delphixx/ ...

  3. Python小白的数学建模课-10.微分方程边值问题

    小白往往听到微分方程就觉得害怕,其实数学建模中的微分方程模型不仅没那么复杂,而且很容易写出高水平的数模论文. 本文介绍微分方程模型边值问题的建模与求解,不涉及算法推导和编程,只探讨如何使用 Pytho ...

  4. AJAX的学习与使用>前端技术系列

    目录 AJAX的学习与使用 什么是AJAX 为什么要使用AJAX AJAX接收服务器响应数据的3种格式 文本格式(重要) JSON格式(重要) 服务器端响应实体类JSON格式的3种方式 修改实体类的t ...

  5. 8.7考试总结(NOIP模拟)[Smooth·Six·Walker]

    前言 踩了挺多以前没踩过的坑... T1 一开始是打了一个 60pts 的 DFS ,在与暴力拍了几组数据保证正确性之后, 突然想到 BFS 可能会更快一些,然后就又码了一个 BFS,又和 DFS 拍 ...

  6. CSS 即将支持嵌套,SASS/LESS 等预处理器已无用武之地?

    最近,有一则非常振奋人心的消息,CSS 即将原生支持嵌套 -- Agenda+ to publish FPWD of Nesting,表示 CSS 嵌套规范即将进入规范的 FWPD 阶段. 目前对应的 ...

  7. Go interface 原理剖析--类型转换

    hi, 大家好,我是 haohognfan. 可能你看过的 interface 剖析的文章比较多了,这些文章基本都是从汇编角度分析类型转换或者动态转发.不过随着 Go 版本升级,对应的 Go 汇编也发 ...

  8. Nacos 笔记

    Nacos 笔记 目录 Nacos 笔记 1. Nacos简介 1.1 主流配置中心对比 1.2 主流注册中心对比 1.3 Nacos特性 2. 安装启动 支持外部 MySQL 3. 配置管理 3.1 ...

  9. markdown的摘要测试

    123456789 1 123456789 2 123456789 3 123456789 4 123456789 5 123456789 6 粗体 123456 划线 123456 斜体 12345 ...

  10. vue3.0安装

    一 .vue3.0安装 vue3.0安装 个人推荐以下2种 (1). 开发工具的对应代码中 插入CDN <script src="https://unpkg.com/vue@next& ...