考场

乍一看都不好做

仔细想想发现 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. 15 道超经典大厂 Java 面试题!重中之重

    从超高频的后端面试题出发,指明学习方向 大家好,我是鱼皮. 还记得我的老弟小阿巴么?他目前正值大一暑假,在家自学编程(刷短视频)中. 他整个大一期间基本都在学习前端.后来,我带他写了一次后端,结果就崩 ...

  2. 记录21.07.23 —— Vue.js基础(二)

    Vue基础(二) 过滤器 过滤器作用 全局过滤器 输出结果 私有过滤器 输出结果 把其中一个做点修改 错误信息 自定义指令 全局自定义指令 私有自定义指令 钩子函数 注意:fond-weight是粗细 ...

  3. scrapy 错误:Missing scheme in request url: %s' % self._url

    先说报错原因:使用了和start_urls同名的参数 我通过scral crawl projename -a start_urls=http:example.com来传start_urls,然后想在项 ...

  4. C语言运算符(杂项运算符 ↦ sizeof & 三元)

    实列 1 #include <stdio.h> 2 3 int main() 4 { 5 int a = 4; 6 short b; 7 double c; 8 int* ptr; 9 1 ...

  5. 为什么大部分的Android开发成为不了架构师

    小团队一般 10 人左右,其中常常是技术最牛的人做架构师(或TL).所以,架构师在广大码农中的占比大概平均不到 10%.而架构师也可以分为初级.中级.高级三档,江湖上真正高水平的软件架构师就更少了. ...

  6. 10 个超棒的 JavaScript 简写技巧

    今天我要分享的是10个超棒的JavaScript简写方法,可以加快开发速度,让你的开发工作事半功倍哦. 开始吧! 1. 合并数组 普通写法: 我们通常使用Array中的concat()方法合并两个数组 ...

  7. Flink EOS如何防止外部系统乱入--两阶段提交源码

    一.前言 根据维基百科的定义,两阶段提交(Two-phase Commit,简称2PC)是巨人们用来解决分布式系统架构下的所有节点在进行事务提交时保持一致性问题而设计的一种算法,也可称之为协议. 在F ...

  8. IDEA Error:java: 无效的源发行版: 11错误

    IDEA Error:java: 无效的源发行版: 11错误 今天在网上下载了一个项目到本地运行报错 Error: Java : 无效的源发行版: 11 ,上网查了很多找到问题所在.项目的 JDK(P ...

  9. DLL劫持漏洞

    写文章的契机还是看沙雕群友挖了十多个DLL劫持的漏洞交CNVD上去了... 就想起来搜集整理一下这部分 0x01 前言 DLL(Dynamic Link Library)文件为动态链接库文件,又称&q ...

  10. Python实现发送邮件(实现单发/群发邮件验证码)

    Python smtplib 教程展示了如何使用 smtplib 模块在 Python 中发送电子邮件. 要发送电子邮件,我们使用 Python 开发服务器,Mailtrap 在线服务和共享的网络托管 ...