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$一 ...
随机推荐
- 【Web动画】科技感十足的暗黑字符雨动画
本文将使用纯 CSS,带大家一步一步实现一个这样的科幻字符跳动背景动画.类似于这样的字符雨动画: 或者是类似于这样的: 运用在一些类似科技主题的背景之上,非常的添彩. 文字的竖排 首先第一步,就是需要 ...
- H5页面自动烟花特效
代码如下: 1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> ...
- js控制单选按钮选中某一项
<!DOCTYPE html><html> <head> <meta charset="utf-8"> <title>& ...
- Python学习的十个阶段,学完神功大成,对应一下看看你自己在哪个阶段
大家好,我是白云. 今天给大家整理了Python学习的十个阶段内容,看看你现在正处于哪个阶段,想学习的朋友也可以根据这个阶段规划学习. 阶段一:Python基础[ 初入江湖] Linux基础 目标: ...
- 使用scrapy搭建大型爬虫系统
最近新项目准备启动,在开始前内容.词库这些都需要提前做好准备,所以就有了这篇文章.在开始动手,看了下行业核心词排在首页的站,发现内容都多得不要不要的,各种乱七八糟的频道.页面模板,心想,如果每个网站. ...
- “入职一年,那个被高薪挖来的Android开发被劝退了。”
其实,在很多小伙伴的想法中,是希望通过跳槽实现薪酬涨幅,可是跳槽不是冲动后决定,应该谨慎啊~ 01 我的学弟,最近向我吐槽,2020 年上半年入职一家公司,当时是高薪挖走的他,所谓钱到位,工作也是充满 ...
- MaterialDesign Or ComboBox 联动查询
<ComboBox Width="200" Height="30" x:Name="ComboxName" Text="{B ...
- 玩转 pyocd
(一) pyocd (1) 什么是pyocd pyocd 是 arm 开发的一个 python 包(python package),该软件包可以使用多种USB调试器对 arm cortex-M 微 ...
- Linux+Apache+Mysql+PHP简单的测试环境搭建
系统版本为:Linux localhost.localdomain 2.6.32-431.el6.x86_64 #1 SMP Fri Nov 22 03:15:09 UTC 2013 x86_64 x ...
- NOIP 模拟 $36\; \rm Cicada 与排序$
题解 \(by\;zj\varphi\) 设 \(rk_{i,j}\) 表示第 \(i\) 个数最后在相同的数里排第 \(j\) 位的概率. 转移时用一个 \(dp\),\(dp_{i,j,0/1}\ ...