[题解向] 正睿Round435
10.14
唔,这一场打得不好。获得了\(\rm 75pts/300pts\)的得分,但是居然可以获得\(\rm 27/69\)的名次,也不至于不满意……毕竟是真不会233
\(\rm T1\)
大概就是字典序那个地方比较爆炸……
于是就考虑奇数开头和偶数开头分开做,对于每种情况调整成一个合法最小代价序列。这个地方有一个贪心,原来在前面的依旧会在前面,在后面的也还会在后面,扫一遍就做完了。
这个贪心里面蕴含着一个性质。\(now_i<i,now_j<j\),即“同向换”,那一定比交叉换代价更小。所以最优的答案会是一段一段相同方向的交换。那么考虑直接枚举对于一段相同方向的、相同奇偶性箭头,换一下彼此的顺序是不会影响结果的。所以就考虑对于同一块进行重排,方法(借鉴的std)大概就是用一个set去维护一下。
int ans[2][MAXN], now[MAXN] ; set <int> s ;
int N, Id[MAXN], base[MAXN], cnt[MAXN], Up[MAXN], cnt1 ;
void print(int *ans){
for (int i = 1 ; i <= N ; ++ i) cout << Up[ans[i]] << " " ;
}
int solve(int zt, int* res){
int fr = 0 ;
int ret = 0, a = zt, b = a ^ 1 ;
if (!a) a = 2 ; if (!b) b = 2 ;
for (int i = 1 ; i <= N ; ++ i){
int &x = Up[base[i]] & 1 ? a : b ;
res[x] = base[i], Id[base[i]] = i, x += 2 ;
}
// print(res) ;
for (int bg = 1 ; bg <= 2 ; ++ bg){
s.clear() ;
for (int l = bg, r = bg ; r <= N ; l = r, fr = 0){
while (r <= N && (Id[res[l]] < l) == (Id[res[r]] < r))
s.insert(r), now[++ fr] = res[r], r += 2 ;
sort(now + 1, now + fr + 1) ;
if (Id[res[l]] < l){
for (int i = 1 ; i <= fr ; ++ i){
int p = *s.lower_bound(Id[now[i]]) ;
s.erase(p), res[p] = now[i] ;
}
}
else {
for (int i = fr ; i >= 1 ; -- i){
int p = *-- s.upper_bound(Id[now[i]]) ;
s.erase(p), res[p] = now[i] ;
}
}
}
}
// print(res) ;
for (int i = 1 ; i <= N ; ++ i) ret += abs(Id[res[i]] - i) ; return ret ;
}
bool comp(int * a, int * b){
for (int i = 1 ; i <= N ; ++ i)
if (a[i] != b[i]) return a[i] < b[i] ;
return 0 ;
}
int main(){
cin >> N ; int i ;
for (i = 1 ; i <= N ; ++ i)
cin >> base[i], cnt1 += (base[i] & 1 == 1), Up[i] = base[i] ; sort(Up + 1, Up + N + 1) ;
for (i = 1 ; i <= N ; ++ i) base[i] = lower_bound(Up + 1, Up + N + 1, base[i]) - Up, base[i] += cnt[base[i]] ++ ;
if (N & 1) solve(N - cnt1 < cnt1, ans[0]), print(ans[0]) ;
else {
int x = solve(0, ans[0]), y = solve(1, ans[1]) ;
if (x < y || (x == y && comp(ans[0], ans[1]))) print(ans[0]) ;
else print(ans[1]) ;
}
return 0 ;
}
\(\rm T2\)
啧,根号分治,没怎么做过qaq。
首先就是\(nq\)暴力比较好写,但是自我感觉我写的暴力复杂度应该是优于普通暴力的,均摊下来或许在\(O(q\cdot \frac{n}{m})\)的亚子,但是似乎并没有这一档部分分,(;'⌒')。
然后就是正解。有一个求连通块的性质,就是当图\(\rm \{V,E\}\)是一棵森林的时候,有\(\rm S=V-E\),其中\(\rm S\)即连通块个数。所以只需要考虑怎么维护边数就好。
考虑根号分治。即对于\(occur[i]\leq \sqrt n\)的颜色直接暴力修改,然后对于与这些块相邻的点,如果也是小颜色就不管,如果是大颜色就打上一个标记,意思是如果这个大颜色修改了的话,会如何影响这个小颜色的贡献。考虑假设\(i,i+1\)这个状态是\((1,1)\),那么修改之后变成\((1,0)\),\(~\text {E-=1}\),但是当时\(i\)变化(\(0\to 1\))的时候是\(\text{E+=1}\)。大概这么分类讨论几波实际上就是抄的std就会发现规律。
然后对于大颜色,每次先算上打的标记(小颜色),然后考虑预处理出相邻大颜色点之间的边,询问时暴力\(\sqrt n\)扫过每一个大颜色计算贡献。
唔,然后就是\(q\sqrt n\)的复杂度了。
int ans1, ans2, E[MAXF][MAXF] ;
int N, M, K, base[MAXN], zt[MAXN], num[MAXN], Id[MAXN], cnt ;
int buc[MAXN], nxt[MAXN], tag[MAXN], s[MAXN], frx[MAXN], Lans, bk[MAXN], big[MAXN] ;
void Pre_links(){
memset(buc, 0, sizeof(buc)) ;
for (int i = N ; i >= 1 ; -- i)
if (!buc[base[i]])
nxt[i] = N + 1, buc[base[i]] = i ;
else nxt[i] = buc[base[i]], buc[base[i]] = i ;
memset(buc, 0, sizeof(buc)) ;
for (int i = 1 ; i <= N ; ++ i)
if (!buc[base[i]]) frx[base[i]] = i, buc[base[i]] = 1 ;
}
void Pre_blocks(){
for (int i = 1 ; i <= N ; ++ i){
scanf("%d", &base[i]) ;
if (base[i] == base[i - 1]) { N --, i -- ; continue ;}
buc[base[i]] ++ ;
}
for (int i = 1 ; i <= K ; ++ i) s[i] = buc[i] ;
for (int i = 1 ; i <= K ; ++ i)
if (buc[i] <= MAXS) num[i] = 1 ;
else num[i] = 2, big[++ cnt] = i, Id[i] = cnt ;
}
int main(){
//freopen("bulb3.in", "r", stdin) ;
//freopen("2.out", "w", stdout) ;
cin >> N >> M >> K ;
Pre_blocks(), Pre_links() ;
for (int i = 1 ; i <= cnt ; ++ i)
for (int j = frx[big[i]] ; j <= N ; j = nxt[j]){
if (j + 1 <= N && num[base[j + 1]] > 1)
E[i][Id[base[j + 1]]] ++ ;
if (j - 1 >= 1 && num[base[j - 1]] > 1)
E[i][Id[base[j - 1]]] ++ ;
}
while (M --){
int x, w ; scanf("%d", &x) ;
w = zt[x] ? -1 : 1, ans1 += w * s[x] ;
if (num[x] < 2){
if (!frx[x]) {
printf("%d\n", ans1 - ans2) ;
continue ;
}
for (int i = frx[x] ; i <= N ; i = nxt[i]) {
int o = base[i + 1], p = base[i - 1] ;
if (num[o] >= 2) tag[o] += w ;
if (num[p] >= 2) tag[p] += w ;
ans2 += (!zt[x] & zt[o]) - (zt[x] & zt[o]) ;
ans2 += (!zt[x] & zt[p]) - (zt[x] & zt[p]) ;
}
}
else {
ans2 += w * tag[x] ;
for (int i = 1 ; i <= cnt ; ++ i)
ans2 += ((!zt[x] & zt[big[i]]) - (zt[x] & zt[big[i]])) * E[Id[x]][i] ;
}
printf("%d\n", ans1 - ans2) ; zt[x] ^= 1 ;
}
return 0 ;
}
\(\rm T3\)
大概是一道小清新题,暴力很好写,然后就是考虑真正地设计状态:
令\(f_{i,j}\)表示前\(i\)个人选出\(j\)个人的集合的概率。
于是有两种转移(以下用\(p_1\)表示小标号赢的概率,\(p_2=1-p_1\)表示大标号赢的概率):
考虑把\(i\)加入进来。那么\(f_{i,j}=f_{i-1,j-1}\cdot p_2^{i-j}+f_{i-1,j}\cdot p_1^{j}\)。前者是必须赢前面的\(i-j\)个人才能进集合,后者是必须输给\(j\)个人才能不在集合里面。
考虑把\(1\)加入进来。那么\(f_{i,j}=f_{i-1,j-1}\cdot p_1^{i-j}+f_{i-1,j}\cdot p_2^{j}\)。跟上面是对称的。
理解嘛…大概就是考虑每次是把当前更大的选进来还是更小的选进来。
然后就是比较神仙的点:联立!联立上面两个式子就会得到:
\]
移项
\]
然后发现就跟\(i\)这一维无关了
#include <cstdio>
#include <cstring>
#include <iostream>
#define LL long long
#define MAXN 1500100
#define Mod 998244353
using namespace std ; LL ans ;
int stk[60], buc[30], cnt = 0, po[MAXN] ;
int N, M, A, B, P1, P2, Len[MAXN], dp[MAXN], f[MAXN] ;
int expow(int a, int b){
int res = 1 ;
while (b){
if (b & 1)
res = 1ll * res * a % Mod ;
a = 1ll * a * a % Mod, b >>= 1 ;
}
return res ;
}
int main(){
int i, j ; po[1] = 1 ;
cin >> N, M = (1 << N) - 1, cin >> A >> B ;
P1 = 1ll * A * expow(B, Mod - 2) % Mod, P2 = ((1 - P1) % Mod + Mod) % Mod ;
for (i = 1 ; i <= M ; ++ i) Len[i] = Len[i - (i & (-i))] + 1 ;
for (i = 2 ; i <= N ; ++ i) po[i] = (1ll * po[i - 1] * po[i - 1] % Mod + 2) % Mod ;
for (i = 1 ; i <= M ; ++ i){
cnt = 0 ; LL P = 1 ;
memset(buc, 0, sizeof(buc)) ;
for (j = 1 ; j <= N ; ++ j)
if ((1 << j - 1) & i)
stk[++ cnt] = j, buc[j] = 1 ;
for (j = 1 ; j <= N ; ++ j) buc[j] += buc[j - 1] ;
for (j = 1 ; j <= cnt ; ++ j){
P = P * expow(P2, stk[j] - 1 - buc[stk[j] - 1]) % Mod ;
P = P * expow(P1, N - stk[j] - buc[N] + buc[stk[j]]) % Mod ;
}
dp[i] = P ;
}
for (i = 1 ; i < M ; ++ i) f[Len[i]] = (f[Len[i]] + dp[i]) % Mod ;
for (i = 1 ; i < N ; ++ i) (ans += 1ll * f[i] * po[i]) %= Mod ; cout << ans << endl ; return 0 ;
}
[题解向] 正睿Round435的更多相关文章
- [题解向] 正睿Round409
\(\rm Link\) 然而泥萌没有权限是看不了题目的233. \(\rm T1\) 大概就是个map,脑残出题人认为(x,x)不属于有序二元组,我可qtmd.于是只拿了\(\rm 60pts\) ...
- 11.6 正睿停课训练 Day17
目录 2018.11.6 正睿停课训练 Day17 A chinese(思路 计数) B physics(单调队列/剪枝 DP) C chemistry(期望 DP) 考试代码 A B C 2018. ...
- 8.10 正睿暑期集训营 Day7
目录 2018.8.10 正睿暑期集训营 Day7 总结 A 花园(思路) B 归来(Tarjan 拓扑) C 机场(凸函数 点分治) 考试代码 A B C 2018.8.10 正睿暑期集训营 Day ...
- 10.31 正睿停课训练 Day13
目录 2018.10.31 正睿停课训练 Day13 A Poker(期望) B Label(高斯消元) C Coin(二分图染色 博弈) 考试代码 A(打表) B 2018.10.31 正睿停课训练 ...
- 11.5 正睿停课训练 Day16
目录 2018.11.5 正睿停课训练 Day16 A 道路规划(思路) B 逻辑判断(枚举 位运算/DP 高维前缀和) C 区间(贪心/树状数组) 考试代码 A B C 2018.11.5 正睿停课 ...
- 11.2 正睿停课训练 Day15
目录 2018.11.2 正睿停课训练 Day15 A 郁闷的小G(二分) B 小G的树(树形DP) C 数的距离(思路) 考试代码 B C 2018.11.2 正睿停课训练 Day15 时间:3.5 ...
- 11.1 正睿停课训练 Day14
目录 2018.11.1 正睿停课训练 Day14 A 字符串 B 取数游戏(贪心) C 魔方(模拟) 考试代码 B C 2018.11.1 正睿停课训练 Day14 时间:3.5h 期望得分:100 ...
- 10.29 正睿停课训练 Day11
目录 2018.10.29 正睿停课训练 Day11 A 线段树什么的最讨厌了(思路 DFS) B 已经没有什么好害怕的了(差分 前缀和) C 我才不是萝莉控呢(DP 贪心 哈夫曼树) 考试代码 A ...
- 10.30 正睿停课训练 Day12
目录 2018.10.30 正睿停课训练 Day12 A 强军战歌(DP 树状数组 容斥) B 当那一天来临(思路) C 假如战争今天爆发(贪心) 考试代码 B C 2018.10.30 正睿停课训练 ...
随机推荐
- 微服务 SpringCloud + docker
最近看到微服务很火,也是未来的趋势,所以就去学习下 好,接下来我们来认识下spring cloud.一.什么是spring cloud?它的中文官网这样说: 微服务架构集大成者,云计算最佳业务实践. ...
- 解决 ubuntu 开机卡死在输入密码界面 && 键盘鼠标失灵!!
近期不知安装了什么package,导致 ubuntu 开机后键盘鼠标一直没法用,刚开始以为是 ubuntu 桌面环境崩溃了,后来发现系统能显示连接到网络.时间也在运行,那应该就是键盘鼠标失灵了. 网上 ...
- 大话设计模式Python实现-工厂方法模式
工厂方法模式(Factory Method Pattern):定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延时到其子类. #!/usr/bin/env python ...
- openssl编译安装
最新版本可以在这个网站下载: https://www.openssl.org/source/ wget https://www.openssl.org/source/openssl-1.1.1c.ta ...
- Vue.js 源码分析(十八) 指令篇 v-for 指令详解
我们可以用 v-for 指令基于一个数组or对象来渲染一个列表,有五种使用方法,如下: <!DOCTYPE html> <html lang="en"> & ...
- 奥展项目笔记07--vue绑定下拉框和checkbox总结
1.vue绑定下拉框 <div class="col-md-1 data"> <select class="form-control " v- ...
- 线程池之ScheduledThreadPoolExecutor线程池源码分析笔记
1.ScheduledThreadPoolExecutor 整体结构剖析. 1.1类图介绍 根据上面类图图可以看到Executor其实是一个工具类,里面提供了好多静态方法,根据用户选择返回不同的线程池 ...
- 在 Javascript 中,为什么给 form 添加了 onsubmit 事件,为什么 IE7/8 还是会提交表单?
参考地址:http://stackoverflow.com/questions/4078245/onsubmit-return-false-has-no-effect-on-internet-expl ...
- 状态(State)模式--设计模式
定义与特点 1.1 定义 状态模式允许一个对象在其内部状态改变的时候改变其行为.这个对象看上去就像是改变了它的类一样. 1.2 特点 状态模式优点: 封装了转换规则,并枚举可能的状态,它将所有与某个状 ...
- Python 学习 第15篇:日期和时间
datetime模块中包含五种基本类型:date.time.datetime.timedelta和tzinfo,tz是time zone的缩写,tzinfo用于表示时区信息. 一,date类型 dat ...