20210811 Dove 打扑克,Cicada 与排序,Cicada 拿衣服
考场
开考感觉 T3 比较可做。T1 看上去不难但毫无思路。
先想了 25min T3,想到一个确定左端点,二分最长的右端点,甚至想到了用猫树维护区间 or and。。。上厕所回来发现假了,没有单调性
T1 还是不会做,T2 甚至不会写暴力。直到 8.10 才结束思考。
T1 暴力有 80pts,先写了
继续看 T3,根据区间变大后四个变量的变化情况想到了分治,又是想了很久发现复杂度假了,心态就炸了。这时候已经 9.20 了,洗了把脸强行冷静,写了 T3 暴力,但状态很差,写错很多细节。
最后 30min 看 T2,感觉可以枚举 rnd() 的值来算出每种情况下的位置,觉得不太好写在归并排序,预处理了的个数组假装它是随机数。但预处理多长却不好确定。一开始是 \(n\),但样例都过不去,瞎胡分析一波感觉是每个数值的元素个数减一的和,也不太对。最终预处理的 \(21\) 位。
res
rk10 80+15+28
T2 后面的点都 T 了,开到 \(20\) 能多拿 20pts
rk1 熊子豪 100+0+92
rk2 yzf 80+0+100
rk3 肖鸣孜 80+100+0
总结
没啥好说的,就是菜
T1 毕竟没想多久,算是有个借口
T2 又是大 DP,练了这么久还是没啥长进,甚至一点思路都没有。不仅有人场切,而且很多人(比如 ycx)都有思路,只是细节问题/没写完。不擅长不是借口,万一正式比赛考出来怎么办,还是得练。练习的时候多自己想,能抵抗多久题解的诱惑提高就有多少
T3 想了很久都没想到点上,还是性质推的不够,确实也没见过这种做法,但还是很多人想出来了。不仅如此,有人常数小拿了 64pts,有人的乱搞 A 了,也有 72pts 的,但我只拿了最基础的暴力分,对于这种数据有梯度的题就要多卡常、多剪枝,剪枝可以大胆一点。
感觉洗脸挺有用的,起码暴力没挂分。
sol
双没时间写了
T1
const int N = 1e5+5;
int n,m;
int mx,fa[N],val[N],cnt[N];
vector<int> vec;
int find(int x) { return fa[x]==x ? x : fa[x]=find(fa[x]); }
void add(int i)
{ if( !cnt[i]++ ) vec.insert(lower_bound(vec.begin(),vec.end(),i),i); }
void del(int i)
{ if( !--cnt[i] ) vec.erase(remove(vec.begin(),vec.end(),i)); }
signed main() {
read(n,m);
For(i,1,n) fa[i] = i, val[i] = 1, add(1);
while( m-- ) {
int op,x,y; read(op);
if( op == 1 ) {
read(x,y); x = find(x), y = find(y);
if( x == y ) continue;
del(val[x]), del(val[y]);
fa[y] = x, val[x] += val[y];
add(val[x]);
} else {
read(x);
LL ans = 0, suf = 0;
if( !x ) {
for(int i : vec) ans += cnt[i] * (cnt[i]-1ll) / 2;
++x;
}
for(auto it = vec.begin(); it != vec.end(); ++it) suf += cnt[*it];
for(auto itl = vec.begin(), itr = itl; itr != vec.end(); ++itl) {
while( itr != vec.end() && *itr-*itl < x ) suf -= cnt[*itr++];
if( itr == vec.end() ) break;
ans += cnt[*itl] * suf;
}
write(ans);
}
}
return iocl();
}
T2
我写了另一种 DP,时间复杂度也是 \(O(n^3)\),但空间复杂度是 \(O(n^2\log n)\),内存访问不连续,比 sol做法 跑得慢
const int N = 505, mod = 998244353, inv2 = 499122177;
int n,a[N];
LL f[10][N][N],g[N][N];
void merge(int u,int l,int r) {
if( l == r ) return f[u][l][l] = 1, void();
int mid = l+r>>1;
merge(u+1,l,mid), merge(u+1,mid+1,r);
memset(g,0,sizeof g);
g[l][mid+1] = 1;
For(i,l,mid+1) For(j,mid+1,r+1) if( i <= mid || j <= r ) {
g[i][j] %= mod;
if( j == r+1 ) g[i+1][j] += g[i][j];
else if( i == mid+1 ) g[i][j+1] += g[i][j];
else if( a[i] < a[j] ) g[i+1][j] += g[i][j];
else if( a[i] > a[j] ) g[i][j+1] += g[i][j];
else g[i+1][j] += g[i][j] * inv2 %mod, g[i][j+1] += g[i][j] * inv2 %mod;
}
For(i,l,r) For(j,l,mid+1) For(k,mid+1,r+1) if( j <= mid || k <= r ) {
if( k == r+1 ) f[u][i][j+k-mid-1] += f[u+1][i][j] * g[j][k] %mod;
else if( j == mid+1 ) f[u][i][j+k-mid-1] += f[u+1][i][k] * g[j][k] %mod;
else if( a[j] < a[k] ) f[u][i][j+k-mid-1] += f[u+1][i][j] * g[j][k] %mod;
else if( a[j] > a[k] ) f[u][i][j+k-mid-1] += f[u+1][i][k] * g[j][k] %mod;
else f[u][i][j+k-mid-1] += (f[u+1][i][j]+f[u+1][i][k]) * g[j][k] %mod * inv2 %mod;
}
For(i,l,r) For(j,l,r) f[u][i][j] %= mod;
sort(a+l,a+r+1);
}
signed main() {
read(n);
For(i,1,n) read(a[i]);
merge(1,1,n);
For(i,1,n) {
LL ans = 0;
For(j,1,n) ans += f[1][i][j] * j %mod;
write(ans%mod,' ');
}
return iocl();
}
T3
const int N = 1e6+5;
int n,m,a[N];
struct Node { int r,o,an; int val() { return o-an; } };
list<Node> lis;
namespace st {
int lg[N],f[20][N],g[20][N];
void init() {
For(i,2,n) lg[i] = lg[i>>1] + 1;
For(i,1,n) f[0][i] = g[0][i] = a[i];
For(j,1,19) for(int i = 1; i+(1<<j)-1 <= n; ++i)
f[j][i] = max(f[j-1][i],f[j-1][i+(1<<j-1)]),
g[j][i] = min(g[j-1][i],g[j-1][i+(1<<j-1)]);
}
int mx(int l,int r) { int k = lg[r-l+1]; return max(f[k][l],f[k][r-(1<<k)+1]); }
int mn(int l,int r) { int k = lg[r-l+1]; return min(g[k][l],g[k][r-(1<<k)+1]); }
}
namespace seg {
#define ls (u<<1)
#define rs (u<<1|1)
struct Node { int l,r,mx; } t[N*4];
void build(int u,int l,int r) {
t[u].l = l, t[u].r = r, t[u].mx = -1;
if( l == r ) return;
int mid = l+r>>1;
build(ls,l,mid), build(rs,mid+1,r);
}
void modify(int u,int l,int r) {
if( l <= t[u].l && t[u].r <= r ) { ckmax(t[u].mx,r-l+1); return; }
if( l <= t[ls].r ) modify(ls,l,r);
if( t[rs].l <= r ) modify(rs,l,r);
}
void print(int u) {
if( t[u].l == t[u].r ) { write(t[u].mx,' '); return; }
ckmax(t[ls].mx,t[u].mx), ckmax(t[rs].mx,t[u].mx);
print(ls), print(rs);
}
#undef ls
#undef rs
}
bool check(list<Node>::iterator it,int l,int r)
{ return it->val()+st::mn(l,r)-st::mx(l,r) >= m; }
signed main() {
read(n,m);
For(i,1,n) read(a[i]);
st::init(), seg::build(1,1,n);
For(i,1,n) {
for(auto it = lis.begin(); it != lis.end(); ++it)
it->o |= a[i], it->an &= a[i];
lis.pb(Node{i,a[i],a[i]});
for(auto itl = lis.begin(), itr = itl; ++itr != lis.end(); )
if( itl->val() == itr->val() ) lis.erase(itl), itl = itr;
else ++itl;
for(auto it = lis.begin(); it != lis.end(); ++it) if( check(it,it->r,i) ) {
int l = 1, r = it->r;
if( it != lis.begin() ) l = (--it)->r+1, ++it;
while( l < r ) {
int mid = l+r>>1;
if( check(it,mid,i) ) r = mid;
else l = mid+1;
}
seg::modify(1,l,i);
break;
}
}
seg::print(1);
return iocl();
}
20210811 Dove 打扑克,Cicada 与排序,Cicada 拿衣服的更多相关文章
- 「10.28」Dove 打扑克(链表)·Cicada 与排序(概率)·Cicada 拿衣服(各种数据结构)
A. Dove 打扑克 考场思考半天线段树树状数组,没有什么想法 打完暴力后突然想到此题用链表实现会很快. 因为只有$n$堆,所以设最多有$x$个不同的堆数,那么$x\times (x-1)/2==n ...
- [CSP-S模拟测试]:Cicada与排序(概率DP)
题目传送门(内部题93) 输入格式 第一行一个整数$n$,代表数列的长度. 接下来一行$n$个数$a_i$,用空格分隔开. 输出格式 输出一行$n$个数,表示原数列上这个位置在执行后的期望位置,注意输 ...
- NOIP 模拟 $36\; \rm Cicada 与排序$
题解 \(by\;zj\varphi\) 设 \(rk_{i,j}\) 表示第 \(i\) 个数最后在相同的数里排第 \(j\) 位的概率. 转移时用一个 \(dp\),\(dp_{i,j,0/1}\ ...
- [UPC10525]:Dove打扑克(暴力+模拟)
题目描述 $Dove$和$Cicada$是好朋友,他们经常在一起打扑克来消遣时光,但是他们打的扑克有不同的玩法. 最开始时,牌桌上会有$n$个牌堆,每个牌堆有且仅有一张牌,第$i$个牌堆里里里那个扑克 ...
- 晚间测试13 A. Dove 打扑克 vector +模拟
题目描述 分析 这道题比较关键的一点就是要看出最终牌数的种类数不会超过 \(\sqrt{n}\) 种 知道了这个性质我们就可以用 \(vector\) 维护一个有序的序列 \(vector\) 中存放 ...
- NOIP 模拟 $36\; \rm Dove 打扑克$
题解 \(by\;zj\varphi\) 引理 对于一个和为 \(n\) 的数列,不同的数的个数最多为 \(\sqrt n\) 证明: 一个有 \(n\) 个不同的数的数列,和最小就是 \(n\) 的 ...
- 题解 Dove 打扑克
传送门 考场上觉得复杂度是假的就没怎么优化,然后考完题解帮我证明了它是真的-- 首先合并可以用并查集维护,可以顺便维护出集合的大小 对于操作2,发现如果 \(size_i\) 是确定的,可以用权值线段 ...
- 数据结构和算法(Golang实现)(20)排序算法-选择排序
选择排序 选择排序,一般我们指的是简单选择排序,也可以叫直接选择排序,它不像冒泡排序一样相邻地交换元素,而是通过选择最小的元素,每轮迭代只需交换一次.虽然交换次数比冒泡少很多,但效率和冒泡排序一样的糟 ...
- csp-s模拟测试91
csp-s模拟测试91 倒悬吃屎的一套题. $T1$认真(?)分析题意发现复杂度不能带$n$(?),计划直接维护答案,考虑操作对答案的影响,未果.突然发现可以动态开点权值线段树打部分分,后来$Tm$一 ...
随机推荐
- ThinkPHP5 5.0.22/5.1.29 远程代码执行漏洞
http://192.168.49.2:8080/index.php?s=/Index/\think\app/invokefunction&function=call_user_func_ar ...
- Scrapy入门到放弃04:下载器中间件,让爬虫更完美
前言 MiddleWare,顾名思义,中间件.主要处理请求(例如添加代理IP.添加请求头等)和处理响应 本篇文章主要讲述下载器中间件的概念,以及如何使用中间件和自定义中间件. MiddleWare分类 ...
- H5页面自动烟花特效
代码如下: 1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> ...
- Nature | 多层次蛋白质组学综合分析冠状病毒侵染宿主细胞的分子机制
冠状病毒是一种自然界普遍存在的单股正链RNA病毒,电镜下呈日冕状或皇冠状,故命名为冠状病毒.在本世纪初短短20年中,共爆发了三次冠状病毒疫情,即2003年SARS-CoV.2012年MERS-CoV和 ...
- Bugku-域名解析
做题之前了解一下域名解析,域名是为了方便记忆而专门建立的一套地址转换系统,要访问一台互联网上的服务器,最终还必须通过IP地址来实现,域名解析就是将域名重新转换为IP地址的过程.一个域名对应一个IP地址 ...
- Dired Mode in Emacs
Start up Dired mode: C-x d; (List dirs: C-x C-d) Hide Dired mode window: q; Mark Mark (for group man ...
- 使用账号密码来操作github? NO!
目录 简介 背景介绍 创建令牌 使用令牌 缓存令牌 使用GCM 总结 简介 最近在更新github文件的时候,突然说不让更新了,让我很是困惑,原因是在2021年8月13号之后,github已经不让直接 ...
- 了解cookie和storage的区别及优缺点
共同点:用于数据的存储. 区别: 1.是否需要添加到http请求头? HTTP Cookie(cookie):在客户端存储会话信息,要求服务器对任意HTTP请求发送set-cookie HTTP头作为 ...
- GO语言的基本语法之变量,常量,条件语句,循环语句
GO语言的基本语法之变量,常量,条件语句,循环语句 作为慕课网得笔记自己看 定义变量: 使用var关键字 var a, b, C bool var s1, s2 string = "hell ...
- DVWA靶场之XSS(Stored)通关
Low: <?php if( isset( $_POST[ 'btnSign' ] ) ) { // Get input $message = trim( $_POST[ 'mtxMessage ...