考前

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. jboss未授权访问

    测试 poc地址 https://github.com/joaomatosf/jexboss

  2. GhostScript 沙箱绕过(命令执行)漏洞(CVE-2019-6116)

    影响范围 Ghostscript 9.24之前版本 poc地址:https://github.com/vulhub/vulhub/blob/master/ghostscript/CVE-2019-61 ...

  3. 关于win7+cenos 7双系统安装

    ---恢复内容开始--- 1,cenos 0 7制作U盘启动 制作工具 http://pan.baidu.com/s/1nv9lpmp 镜像自备 2,安装centos 7 释放磁盘空间,如:20G.用 ...

  4. 论文笔记:(2019)GAPNet: Graph Attention based Point Neural Network for Exploiting Local Feature of Point Cloud

    目录 摘要 一.引言 二.相关工作 基于体素网格的特征学习 直接从非结构化点云中学习特征 从多视图模型中学习特征 几何深度学习的学习特征 三.GAPNet架构 3.1 GAPLayer 局部结构表示 ...

  5. 手写Pascal解释器(一)

    目录 一.编写解释器的动机 二.part1 三.part2 四.part3 一.编写解释器的动机 学习了Vue之后,我发现对字符串的处理对于编写一个程序框架来说是非常重要的,就拿Vue来说,我们使用该 ...

  6. Blazor 路由及导航开发指南

    翻译自 Waqas Anwar 2021年4月2日的文章 <A Developer's Guide To Blazor Routing and Navigation> [1] 检查传入的请 ...

  7. C++STL—string类

    string容器 1.1 string容器的基本概念 string容器是一个类 这个容器中有一个指针,指针维护了一个数组 string容器提供copy.find.insert.replace等等功能 ...

  8. Vue2.x响应式原理

    一.回顾Vue响应式用法 ​ vue响应式,我们都很熟悉了.当我们修改vue中data对象中的属性时,页面中引用该属性的地方就会发生相应的改变.避免了我们再去操作dom,进行数据绑定. 二.Vue响应 ...

  9. 【Vulnhub】 DC-4 靶机

    Vulnhub DC-4 一.环境搭建 下载链接:https://www.vulnhub.com/entry/dc-4,313/ 解压后用VMware打开,导入虚拟机 网卡配置看个人习惯,我喜欢NAT ...

  10. Ajax 局部刷新 异步提交

    AJAX简介 局部刷新,异步提交. AJAX 不是新的编程语言,而是一种使用现有标准的新方法.它最大的有点就是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容. 浏览器朝后端发送请 ...