考场

开考感觉 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 拿衣服的更多相关文章

  1. 「10.28」Dove 打扑克(链表)·Cicada 与排序(概率)·Cicada 拿衣服(各种数据结构)

    A. Dove 打扑克 考场思考半天线段树树状数组,没有什么想法 打完暴力后突然想到此题用链表实现会很快. 因为只有$n$堆,所以设最多有$x$个不同的堆数,那么$x\times (x-1)/2==n ...

  2. [CSP-S模拟测试]:Cicada与排序(概率DP)

    题目传送门(内部题93) 输入格式 第一行一个整数$n$,代表数列的长度. 接下来一行$n$个数$a_i$,用空格分隔开. 输出格式 输出一行$n$个数,表示原数列上这个位置在执行后的期望位置,注意输 ...

  3. NOIP 模拟 $36\; \rm Cicada 与排序$

    题解 \(by\;zj\varphi\) 设 \(rk_{i,j}\) 表示第 \(i\) 个数最后在相同的数里排第 \(j\) 位的概率. 转移时用一个 \(dp\),\(dp_{i,j,0/1}\ ...

  4. [UPC10525]:Dove打扑克(暴力+模拟)

    题目描述 $Dove$和$Cicada$是好朋友,他们经常在一起打扑克来消遣时光,但是他们打的扑克有不同的玩法. 最开始时,牌桌上会有$n$个牌堆,每个牌堆有且仅有一张牌,第$i$个牌堆里里里那个扑克 ...

  5. 晚间测试13 A. Dove 打扑克 vector +模拟

    题目描述 分析 这道题比较关键的一点就是要看出最终牌数的种类数不会超过 \(\sqrt{n}\) 种 知道了这个性质我们就可以用 \(vector\) 维护一个有序的序列 \(vector\) 中存放 ...

  6. NOIP 模拟 $36\; \rm Dove 打扑克$

    题解 \(by\;zj\varphi\) 引理 对于一个和为 \(n\) 的数列,不同的数的个数最多为 \(\sqrt n\) 证明: 一个有 \(n\) 个不同的数的数列,和最小就是 \(n\) 的 ...

  7. 题解 Dove 打扑克

    传送门 考场上觉得复杂度是假的就没怎么优化,然后考完题解帮我证明了它是真的-- 首先合并可以用并查集维护,可以顺便维护出集合的大小 对于操作2,发现如果 \(size_i\) 是确定的,可以用权值线段 ...

  8. 数据结构和算法(Golang实现)(20)排序算法-选择排序

    选择排序 选择排序,一般我们指的是简单选择排序,也可以叫直接选择排序,它不像冒泡排序一样相邻地交换元素,而是通过选择最小的元素,每轮迭代只需交换一次.虽然交换次数比冒泡少很多,但效率和冒泡排序一样的糟 ...

  9. csp-s模拟测试91

    csp-s模拟测试91 倒悬吃屎的一套题. $T1$认真(?)分析题意发现复杂度不能带$n$(?),计划直接维护答案,考虑操作对答案的影响,未果.突然发现可以动态开点权值线段树打部分分,后来$Tm$一 ...

随机推荐

  1. java继承基础详解

    java继承基础详解 继承是一种由已存在的类型创建一个或多个子类的机制,即在现有类的基础上构建子类. 在java中使用关键字extends表示继承关系. 基本语法结构: 访问控制符 class 子类名 ...

  2. solr(CVE-2019-17558)远程命令执行

    影响版本 Apache Solr 5.x到8.2.0版本 测试 https://github.com/jas502n/CVE-2019-0193

  3. ES6新特征

    1.块级作用域 {   }  就是块级作用域,还包括if.else.for.while...下都属于块级作用域. let 声明的变量不存在变量的提升,不允许let反复声明同一个变量:块级作用域下let ...

  4. 5G时代,视频会议的未来

    过去,2G打开了了移动互联网天下,3G促成了即时通信,诞生了QQ.微信等巨头,4G 带来了短视频兴起,字节跳动等公司崛起.2.3.4G的出现促成了移动互联网10年繁荣.而5G的出现,也会促成至少10年 ...

  5. WPF Combox实现下拉多选,可选中多个值

    自定义多选MultiCombox,可以实现下拉列表多选 using System; using System.Collections.Generic; using System.Collections ...

  6. Java面向对象13——抽象类

    抽象类  package oop.demon01.demon08; ​ //abstract 抽象类: 类 extends: 类---单继承   (接口可以多继承) public abstract c ...

  7. 靶机DC-2 rbash绕过+git提权

    这个靶机和DC-1一样,一共5个flag.全部拿到通关. root@kali:/home/kali# nmap -sP 192.168.1.* 先扫一下靶机的IP地址,拿到靶机的地址为192.168. ...

  8. Git8.3k星,十万字Android主流开源框架源码解析,必须盘

    为什么读源码 很多人一定和我一样的感受:源码在工作中有用吗?用处大吗?很长一段时间内我也有这样的疑问,认为哪些有事没事扯源码的人就是在装,只是为了提高他们的逼格而已. 那为什么我还要读源码呢?一刚开始 ...

  9. ES6继承和ES5继承是完全一样的么?

    继承方式 ES5 prototype 继承 通过原型链(构造函数 + [[prototype]])指向实现继承. (备注:后续__proto__我都会写成[[prototype]]这种形式) 子类的 ...

  10. antd+vue3实现动态表单的自动校验

    由于vue3用的人还不多,所以有些问题博主踩了坑只能自己爬出来了,特此做个记录.如有错误,请大家指正. 回归正题,我所做的业务是,动态添加表单项,对每一项单独做校验,效果如下: 主要代码如下: 1 & ...