考场

乍一看都不好做

仔细想想发现 T1 的绝对值特别好,轮流选剩余的最大/最小值就行了

T2 又要计数,直接想部分分,发现一个 sb 容斥就有 35ps(但数据锅了,只有 25pts)

T3 什么玩意,发现线段树不会操作 6(线段树分裂啊,昨天刚打了板子),LCT 不会操作 2

,但 sub3(只维护黑点) 4(线段树维护序列) 都会

T4 高消直接死了,一分都没有。两个 sub 都是链,什么情况(考场上把 \(1\) 看成 \(i\)了)

迅速写+拍完前两题

想了想 T4 的系数递推,但列出的式子很不可做;貌似也不能高消一次求出所有答案,puts 样例了

感觉 T3 是比较擅长的题型,又想了很久,sub2 也会了(确定联通块后线段树),但直到 10.20 才开始写,最终只写完了 sub1 4

res

rk3 100+28+25+0(显示的是 rk4,因为出榜时 T3 在 judging。。。)

rk1 张王美誉 100+11+60+0

rk2 牛宏昊 100+44+10+0

rk4 付文暄 90+11+10+20(显示的是 rk3 的氪金玩家)

总结

想的太浅了,很多地方就差一点,还是要多思考,不要用写代码的勤奋掩盖思维的懒惰。

T3 正解就是在 sub3 的基础上加了个树剖、线段树,T4 给了菊花,sub3 的做法很明显(不过看错题也没啥好说的)

sol

T1

模拟。考场代码:

const int N = 3e5+5;
int n;
LL a[N]; LL ans,pre[N],suf[N]; signed main() {
// freopen("a.in","r",stdin);
// freopen("a.out","w",stdout);
read(n);
For(i,1,n) read(a[i]); sort(a+1,a+n+1);
For(i,1,n) pre[i] = pre[i-1] + a[i];
rFor(i,n,1) suf[i] = suf[i+1] + a[i];
for(int i = 1, l = 0, r = n+1; i <= n; ++i) {
if( i & 1 ) {
++l;
ans += (a[l] * (l-1) - pre[l-1]) + (suf[r] - a[l] * (n-r+1));
} else {
--r;
ans += (a[r] * l - pre[l]) + (suf[r+1] - a[r] * (n-r));
}
write(ans);
}
return iocl();
}
T2

发现暴力容斥时边集具体是什么并不重要,只要知道有多少条边即可。考虑树形 DP,设 \(f[u,i,0/1/2/3]\) 为子树 \(u\) 选 \(i\) 条边不合法,点 \(u\) 不选/选入边/选出边/都选的方案数。(显然一个点不能同时使两条入边/出边不合法)

const int N = 5e3+5, mod = 998244353;
int n,mm=1,head[N],to[N*2],w[N*2],nxt[N*2]; int siz[N];
LL ans,fac[N],f[N][N][4],g[N][4]; void dfs(int u,int fa) {
siz[u] = 1, f[u][0][0] = 1;
for(int e = head[u], v; v = to[e], e; e = nxt[e]) if( v != fa ) {
dfs(v,u);
memset(g,0,sizeof g);
For(i,0,siz[u]) For(j,0,siz[v]) {
LL fv = (f[v][j][0]+f[v][j][1]+f[v][j][2]+f[v][j][3]) %mod;
For(k,0,3) g[i+j][k] += f[u][i][k] * fv %mod;
if( w[e] )
g[i+j+1][2] += f[u][i][0] * (f[v][j][0]+f[v][j][2]) %mod,
g[i+j+1][3] += f[u][i][1] * (f[v][j][0]+f[v][j][2]) %mod;
else
g[i+j+1][1] += f[u][i][0] * (f[v][j][0]+f[v][j][1]) %mod,
g[i+j+1][3] += f[u][i][2] * (f[v][j][0]+f[v][j][1]) %mod;
}
siz[u] += siz[v];
For(i,1,siz[u]) For(j,0,3) f[u][i][j] = g[i][j] %mod;
}
} signed main() {
read(n);
fac[0] = 1; For(i,1,n) fac[i] = fac[i-1] * i %mod;
For(i,1,n-1) {
int x,y; read(x,y);
to[++mm] = y, w[mm] = 1, nxt[mm] = head[x], head[x] = mm;
to[++mm] = x, w[mm] = 0, nxt[mm] = head[y], head[y] = mm;
}
dfs(1,0);
For(i,0,n-1)
ans += (i+1&1?1:-1) * fac[n-i] * (f[1][i][0]+f[1][i][1]+f[1][i][2]+f[1][i][3]) %mod;
write((ans%mod+mod)%mod);
return iocl();
}
T3

好题,需要很多 DS 技巧

发现每个白点的权值并不重要,只要知道它归属的黑点即可(可以树剖+set 单 \(\log\) 维护)。线段树维护每个黑点的权值和管辖点数,BIT 辅助

细节较多。

typedef unsigned U;

const int N = 3e5+5;
int n,m,fa[N]; int ind,dep[N],siz[N],son[N],top[N],dfn[N],rdfn[N];
VI to[N];
set<int> s[N];
void dfs1(int u) {
dep[u] = dep[fa[u]]+1, siz[u] = 1;
for(int v : to[u]) {
dfs1(v);
siz[u] += siz[v];
if( siz[v] > siz[son[u]] ) son[u] = v;
}
}
void dfs2(int u,int t) {
top[u] = t, dfn[u] = ++ind, rdfn[ind] = u;
if( son[u] ) dfs2(son[u],t);
for(int v : to[u]) if( v != son[u] ) dfs2(v,v);
}
int belong(int u) {
for(int v; v = top[u]; u = fa[top[u]])
if( !s[v].empty() && *s[v].begin() <= dep[u] ) {
auto it = s[v].upper_bound(dep[u]);
return rdfn[dfn[u]-(dep[u]-*--it)];
}
} struct BIT {
U t1[N],t2[N];
void add(int i,U x) { for(int j=i;j<=n;j+=j&-j) t1[j] += x, t2[j] += i*x; }
U sum(int i)
{ U res=0; for(int j=i;j;j-=j&-j) res += (i+1)*t1[j]-t2[j]; return res; }
void modify(int l,int r,U x) { add(l,x), add(r+1,-x); }
U query(int l,int r) { return sum(r) - sum(l-1); }
} bit; #define ls (u<<1)
#define rs (u<<1|1)
struct Node { int l,r; U siz,val,sum,add; } t[N*4];
void up(int u) {
t[u].siz = t[ls].siz + t[rs].siz,
t[u].val = t[ls].val + t[rs].val,
t[u].sum = t[ls].sum + t[rs].sum;
}
void down(int u,U x) { t[u].val += x, t[u].sum += t[u].siz*x, t[u].add += x; }
void down(int u) { down(ls,t[u].add), down(rs,t[u].add), t[u].add = 0; }
void build(int u,int l,int r) {
t[u].l = l, t[u].r = r;
if( l == r ) return;
int mid = l+r>>1;
build(ls,l,mid), build(rs,mid+1,r);
}
void addsiz(int u,int p,U x) {
if( t[u].l == t[u].r ) return t[u].siz += x, t[u].sum += x*t[u].val, void();
down(u);
addsiz( p<=t[ls].r?ls:rs ,p,x);
up(u);
}
void addval(int u,int l,int r,U x) {
if( l <= t[u].l && t[u].r <= r ) return down(u,x);
down(u);
if( l <= t[ls].r ) addval(ls,l,r,x);
if( t[rs].l <= r ) addval(rs,l,r,x);
up(u);
}
void covval(int u,int p,U x) {
if( t[u].l == t[u].r ) return t[u].val = x, t[u].sum = x*t[u].siz, void();
down(u);
covval( p<=t[ls].r?ls:rs ,p,x);
up(u);
}
U qsiz(int u,int l,int r) {
if( l > r ) return 0;
if( l <= t[u].l && t[u].r <= r ) return t[u].siz;
down(u);
U res = 0;
if( l <= t[ls].r ) res = qsiz(ls,l,r);
if( t[rs].l <= r ) res += qsiz(rs,l,r);
return res;
}
U qval(int u,int p) {
if( t[u].l == t[u].r ) return t[u].val;
down(u);
return qval( p<=t[ls].r?ls:rs ,p);
}
U qsum(int u,int l,int r) {
if( l > r ) return 0;
if( l <= t[u].l && t[u].r <= r ) return t[u].sum;
down(u);
U res = 0;
if( l <= t[ls].r ) res = qsum(ls,l,r);
if( t[rs].l <= r ) res += qsum(rs,l,r);
return res;
}
#undef ls
#undef rs signed main() {
read(n,m);
For(i,2,n) read(fa[i]), to[fa[i]].pb(i);
dfs1(1), dfs2(1,1), build(1,1,n);
s[1].insert(1), addsiz(1,1,n);
while( m-- ) {
int op,u,v,l,r; U x,sizu; read(op,u); l = dfn[u], r = dfn[u]+siz[u]-1;
switch(op) {
case 1: write(qval(1,dfn[belong(u)])+bit.query(l,l)); break;
case 2: read(x); addval(1,l,l,x); break;
case 3:
write(qval(1,dfn[belong(u)])*(siz[u]-qsiz(1,l+1,r)) +
qsum(1,l+1,r) + bit.query(l,r));
break;
case 4: read(x); addval(1,l,r,x); break;
case 5:
v = belong(u), s[top[u]].insert(dep[u]);
sizu = siz[u]-qsiz(1,l+1,r);
covval(1,l,qval(1,dfn[v])), addsiz(1,l,sizu);
addsiz(1,dfn[v],-sizu);
break;
default:
v = belong(fa[u]), s[top[u]].erase(dep[u]);
sizu = siz[u]-qsiz(1,l+1,r);
U valu = qval(1,l), valv = qval(1,dfn[v]);
covval(1,l,0), addsiz(1,l,-sizu);
addsiz(1,dfn[v],sizu);
bit.modify(l,r,valu-valv), addval(1,l,r,-(valu-valv));
}
}
return iocl();
}
T4

先鸽了

20210823 数数,数树,鼠树,ckw的树的更多相关文章

  1. 8.23考试总结(NOIP模拟46)[数数·数树·鼠树·ckw的树]

    T1 数数 解题思路 大概是一个签到题的感觉...(但是 pyt 并没有签上) 第一题当然可以找规律,但是咱们还是老老实实搞正解吧... 先从小到大拍个序,这样可以保证 \(a_l<a_r\) ...

  2. 「洛谷1903」「BZOJ2120」「国家集训队」数颜色【带修莫队,树套树】

    题目链接 [BZOJ传送门] [洛谷传送门] 题目大意 单点修改,区间查询有多少种数字. 解法1--树套树 可以直接暴力树套树,我比较懒,不想写. 稍微口胡一下,可以直接来一个树状数组套主席树,也就是 ...

  3. Codeforces Round #404 (Div. 2) E. Anton and Permutation(树状数组套主席树 求出指定数的排名)

    E. Anton and Permutation time limit per test 4 seconds memory limit per test 512 megabytes input sta ...

  4. 计算两个日期之间相差的年数月数天数(JS实现)

    前言 如何计算年龄?我的第一直觉做法:(当前时间戳 - 出生时的时间戳)/ (365*86400)  所得结果向下取整.后来发现这种做法获得的结果不准确,不是多了一岁就是少了一岁,不能简单粗暴的这么处 ...

  5. HDU 1068 Girls and Boys(最大独立集合 = 顶点数 - 最大匹配数)

    HDU 1068 :题目链接 题意:一些男孩和女孩,给出一些人物关系,然后问能找到最多有多少个人都互不认识. 转换一下:就是大家都不认识的人,即最大独立集合 #include <iostream ...

  6. 卡特兰数 Catalan数 ( ACM 数论 组合 )

    卡特兰数 Catalan数 ( ACM 数论 组合 ) Posted on 2010-08-07 21:51 MiYu 阅读(13170) 评论(1)  编辑 收藏 引用 所属分类: ACM ( 数论 ...

  7. HDU 4160 Dolls (最小路径覆盖=顶点数-最大匹配数)

    Dolls Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submiss ...

  8. catalan 数——卡特兰数(转)

    Catalan数——卡特兰数 今天阿里淘宝笔试中碰到两道组合数学题,感觉非常亲切,但是笔试中失踪推导不出来后来查了下,原来是Catalan数.悲剧啊,现在整理一下 一.Catalan数的定义令h(1) ...

  9. JS 实现计算一段文字中的字节数,字母数,数字数,行数,汉字数。

    看到了匹配,第一个想到了用正则表达式,哈哈,果然很方便.不过正则表达式高深莫测!我还没有研究明白啊..目前学了点皮毛.代码如下: <!DOCTYPE html PUBLIC "-//W ...

  10. 【Kafka】Kafka-分区数-备份数-如何设置-怎么确定-怎么修改

    Kafka-分区数-备份数-如何设置-怎么确定-怎么修改 kafka partition 数量 更新_百度搜索 kafka重新分配partition - - CSDN博客 如何为Kafka集群选择合适 ...

随机推荐

  1. PASS-单组目标值法的样本量计算

    临床试验的参数估计中,评价指标有确定的估计目标 ,临床试验目的需通过参数估计(含相应的可信区间估计)的方法证明评价指标不低于目标值时,可根据单组目标值法样本量公式计算. 例:欲证明器械A的诊断准确性非 ...

  2. Jmeter RMI 反序列化命令执行漏洞(CVE-2018-1297)

    下载ysoserial,git git clone https://github.com/frohoff/ysoserial.git cd ysoserialmvn clean package -Ds ...

  3. MySQL执行计划【explain】详解

    本文已经收录到github仓库,仓库用于分享Java相关知识总结,包括Java基础.MySQL.Springboot.mybatis.Redis.rabbitMQ等等,欢迎大家提pr和star! gi ...

  4. 计算机网络笔记Part1 概述

    总目录 1.计算机网络的功能.组成.分类 1.1功能 数据通信 资源共享 分布式处理 提高可靠性 负载均衡 1.2组成部分 硬件 软件 协议 1.3分类 按分布范围 广域网 WAN 城域网 MAN 局 ...

  5. Java 7 新特性之try-with-resources实践理解

    想象这么一个情景,我们需要使用一个资源,在使用完之后需要关闭该资源,并且使用该资源的过程中有可能有异常抛出.此时我们都会想到用try-catch语句,在finally中关闭该资源.此时会有一个问题,如 ...

  6. SVG和Canvas的区别?

    什么是SVG? SVG(可缩放矢量图形)编辑可缩放矢量图形是基于可扩展标记语言(标准通用标记语言的子集),用于描述二维矢量图形的一种图形格式.它由万维网联盟制定,是一个开放标准. 什么是 Canvas ...

  7. C++水仙花 (如:153 = 1*1*1 + 5*5*5 + 3*3*3)

    1 #include <iostream> 2 #include <ctime> 3 using namespace std; 4 5 int main() 6 { 7 int ...

  8. 内置函数 字符串比较 strcmp 登录密码

    1 //内置函数 字符串比较 strcmp 2 // 原理:将两个字符串从首字母开始,按照ASCII码的顺序逐个比较 3 //字符串1 == 字符串2 返回0 4 //字符串1 < 字符串2, ...

  9. 字符串对比 BASIC-15

    字符串对比 代码 import java.util.Scanner; /*给定两个仅由大写字母或小写字母组成的字符串(长度介于1到10之间),它们之间的关系是以下4中情况之一: 1:两个字符串长度不等 ...

  10. erlang学习笔记

    安装 Ubuntu Server上: sudo apt-get install erlang 如果安装时下载 太慢,可手工下载deb包( esl-erlang_16.a-rc1_ubuntu_prec ...