2023.9.9

  • 赛时因为开了火车头喜提 \(0\) 分。

A

P7502 「HMOI R1」不知道是啥的垃圾题

维护一个可重集,支持:

  • 插入一个二元组。

  • 删除一个二元组,保证之前存在。

  • 给出二元组 \((x,y)\),问有多少个可重集内的二元组 \((a,b)\) 满足 \(x\oplus a>y\oplus b\).

\(m\le 2\times 10^5\)\(0\le x,y\le 10^{18}\).

容易想到 trie,有四个分叉记录 \(x,y\) 当前位的值。

然后思考一下怎么求答案。发现递归下去会导致一次查询的递归数为 \(O(m)\).

发现递归下去的当前位异或和与 \(x\oplus y\) 相同,于是考虑插入的时候只记录当前异或和的节点。

#include<bits/stdc++.h>
#define ll long long
#define N 200010
#define L 62
using namespace std;
ll read(){
	ll x=0,w=1;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
	while(isdigit(ch))x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
	return x*w;
}
int s[N*L][2][2],h[N*L][2],tot,rt;
int opt;ll x,y;
#define g(x) (((x)>>d)&1)
void ins(int &r,int d){
	if(d==-1)return;
	s[r?r:r=++tot][g(x)][g(y)]+=3-opt*2;
	ins(h[r][g(x^y)],d-1);
}
int qry(int r,int d){
	if(!r||d==-1)return 0;
	return s[r][!g(x)][g(y)]+qry(h[r][g(x^y)],d-1);
}
int main(){
	int T=read();
	while(T--){
		opt=read(),x=read(),y=read();
		if(opt!=3)ins(rt,L-1);
		if(opt==3)printf("%d\n",qry(rt,L-1)); 
	}
	
	return 0;
}

B

\(n\) 个物品,第 \(i\) 个物品在 \(t\) 时刻的价值为 \(k_it+b_i\).

求一个最小的时刻 \(t\),满足选择至多 \(m\) 个物品的最大价值 \(\ge S\).

\(m\le n\le 10^6\)\(|b_i|\le 10^9\)\(|k_i|\le 10^6\)\(0\le S\le 10^{18}\).

考虑答案随着 \(t\) 的变化。

对于 \(\sum k<0\) 的,它们一定在某个时刻之前选最优。

对于 \(\sum k\ge 0\) 的可以成为 \(t\) 较大时的答案。

所以你发现这个函数是个 U 形的壳。

对于这个极值分成两部分求解。

  • \(k<0\)

此时一定有 \(t=0\).

  • \(k>0\)

可以直接二分一个 \(t\),把最大的 \(m\) 项加起来。

这一 part 是 \(O(n\log n\log V)\) 的,容易发现瓶颈在于排序。

nth_element 支持 \(O(n)\) 将把序列的前 \(k-1\) 小放在前 \(k-1\) 位,第 \(k\) 小放在第 \(k\) 位。

这个是 CSP-S2020 初赛的一个东西。

然后就做完了。


C

P9566 [SDCPC2023] Difficult Constructive Problem

给出一个 \(01\) 串,有通配符,问使得串中相邻不同字符对数恰好为 \(k\) 的字典序最小的字符串。

或判断无解。多测。

\(0\le k<n\le 10^5\)\(\sum n\le 10^6\).

有一档部分分是首尾都不为通配符。考虑从这个入手。

容易发现修改一位不会使得 \(cnt\) 的奇偶性改变。

可以求出 \(cnt\) 的上下界 \(mn,mx\).

那么如果 \(k\not\equiv cnt\space(\operatorname{mod}2)\) 或者 \(k\not\in[mn,mx]\) 无解。

实际上可以将首尾的 \(?\) 拆成 \(0\)\(1\).

先令所有 \(?\)\(0\),从后往前贪心构造。

\(cnt=k\) 时最优,直接输出。

\(cnt>k\) 时,令 \(?\) 所在的 \(101\rightarrow 111\).

\(cnt<k\) 时,令 \(?\) 所在的 \(000\rightarrow 010\).

不太好写。


D

对于树上的每个点,将其视为根,在树上选出 \(k\) 条从根开始的路径,最小化每个点到路径的最小距离乘上 \(w_i\) 之和。

\(n\le 2\times 10^5\)\(1\le k\le n\)\(1\le w_i\le 10^6\).

不思考,骗完部分分跑路。

posted @ 2023-09-09 14:23  SError  阅读(21)  评论(0编辑  收藏  举报