Codeforces Round #616 部分题解

老年选手诈尸?

A,B

咕了。

C - Prefix Enlightenment

很容易看出这个限制条件可以推出每个点最多被两个集合包含。按照套路,很容易联想到给这两个集合连一条边,表示他们的状态要相同/不同。

因为保证了有解,所以从左往右扫的时候拿并查集维护一下每个连通块的二分图情况,选较小的那一边。

如果只被一个集合覆盖,那么就相当于强制这个集合选/不选,在做并查集的时候特判一下即可。

代码咕了。

D - Coffee Varieties (hard version)

作为一名憨憨,做法当然要与正解不同。(当然常数也比正解差……)

容易想到每种咖啡在最左边的位置统计。考虑暴力,枚举两个位置\(i<j\),加入\(i\),加入\(j\),清空。这样可以过\(K=1\)的情况。

考虑每\(K\)个点(注意不是和题解一样\(\frac K 2\))分一个块。如果我们加入\(A\)块之后再加\(B\)块,那么\(B\)块中的每个点都与\(B\)块中的前缀和\(A\)块中的后缀做了比较。如果我们倒着加入\(A\)块之后再倒着加\(B\)块,那么\(B\)块中的每个点都与\(B\)块中的后缀和\(A\)块中的前缀做了比较。可以发现,此时\(B\)块中的每个点都和\(A\)块的每个点做了比较。

先不考虑\(B\)块中点会和比自己靠后的点作比较的问题,那么只要对于任意两个块都这么做一遍就行了。然而常数不太行。

我们先做正着加的情况。考虑做完两个块之后不清空,利用原有的信息。建一张图,\(i\)块向\(j\)块连边(\(i<j\)),走这一条边相当于在队列中是\(i\)块时加入\(j\)块。那么我们需要每条边都走一遍。考虑给这个图加一些额外边,使得它存在欧拉回路,这样就可以一次走完。注意到第\(i\)个块和第\(\frac n K -i+1\)个块的出度入度相匹配,可以额外连\((\frac n K -i+1,i,\frac n K -2*i+1)\)的边,于是每个点的入度出度都相等了,可以跑欧拉回路。此时用的询问次数是\(Km\)的,\(m\)大概是\(\frac {3n^2}{4K^2}\)。

我们希望反着加的情况可以用类似的方法解决,但是反着加的时候\(B\)块中的每个点都与\(B\)块中的后缀做了比较,这不是我们想要的。

注意到正着加的时候我们已经把一些点给毙掉了,剩下的点在同一块中是互不相同的,于是可以倒着加的时候不加入被毙掉的点,而是加一些同块中还活着的点充数。

于是就做完了,询问次数几乎顶着上界,但是不需要清空队列。

我才不告诉你我没看懂正解呢

代码:https://codeforces.com/contest/1290/submission/73847748

E - Cartesian Tree

做这题的前置知识:定义\(maxr(l)\)表示最大的\(r\),使得\([l,r]\)是笛卡尔树中的一个区间,不存在则是\(null\)。\(minl(r)\)类似。那么对于笛卡尔树中的一个区间\([l,r]\),只要不是根,那么\(maxr(l)=r\)和\(minl(r)=l\)就恰好会满足一个。

回到这题,考虑把插入换成往已经确定的位置里填数,也就是允许序列中有空位。

那么\([l,r]\)的子树大小就是\([l,r]\)中的非空位置个数,也就是\(fp(r)-fp(l-1)\)。

考虑把这个东西用前置知识拆开,那么答案就是\(\sum\limits_{maxr(l)\neq null} fp(maxr(l))-\sum\limits_{maxr(l)\neq null} fp(l-1)+\sum\limits_{minl(r)\neq null} fp(r)-\sum\limits_{minl(r)\neq null} fp(minl(r)-1)\),再减掉一些关于根的常数。

据说前后是对称的,那么我们只考虑前面两项。

发现\(maxr(l)\neq null\)等价于\(p_{l-1}>p_l\),于是第二项很好做。

对于第一项,考虑如何加入一个最大值后维护\(maxr(l)\)。由于\(maxr(l)\)就是\((l,n+1]\)中第一个比\(p_{l-1}\)大的位置减一,所以加入最大值就只会给前缀取min,以及单点修改自己和后继的\(maxr\)。

你发现这东西可以segment tree beats维护,而套上个\(fp\)其实也差不多,在外面额外用树状数组维护一下\(fp\)就好了。

大概是这样吧,代码暂时咕了,下午补。

F

咕了。

原文地址:https://www.cnblogs.com/p-b-p-b/p/12537456.html

时间: 2024-09-29 17:38:10

Codeforces Round #616 部分题解的相关文章

Codeforces Round #616 (Div. 2)解题报告

Codeforces Round #616 (Div. 2)解题报告 A. Even But Not Even 找两个奇数就行了. #include<bits/stdc++.h> using namespace std; void solve() { int n; string s; cin >> n >> s; string ans = ""; for(int i = 0; i < n; i++) { if(int(s[i] - '0')%2

Educational Codeforces Round 64部分题解

Educational Codeforces Round 64部分题解 A 题目大意:给定三角形(高等于低的等腰),正方形,圆,在满足其高,边长,半径最大(保证在上一个图形的内部)的前提下. 判断交点个数是否有限,如果有限,输出. 很明显当正方形套三角形或者三角形套正方形是交点个数是无限的(因为有一条边相交) 其他图形的嵌套交点个数比较好判断,不多赘述 但是注意坑点: 当按照矩形,园,三角这样的顺序是,三角与圆的一个交点是与圆和正方形的交点重合的,判一下就好了 #include<cstdio>

Codeforces Round #616 题解

A题 我们注意到如果存在两个奇数,那么就能满足题目条件,所以我们就从头寻找两个奇数,没有的话就是无解 #include<iostream> #include<algorithm> #include<cstdio> #include<cmath> #include<vector> #include<string> #include<cstring> #include<map> using namespace st

Codeforces Round #616 (Div. 2) 题解

A. Even But Not Even 题意: 定义一个数所有位置的和为偶数它本身不为偶数的数为ebne,现在给你一个数字字符串,你可以删除任意位置上的数字使其变为ebne输出任意改变后的结果,如果不能则输出-1 思路: 比赛的时候分类讨论过的...真是愚蠢至极妈的 其实只要看字符串中奇数的个数就好了,如果小于两个则肯定不行,如果大于两个则直接按相对位置输出任意两个就好了 #include<iostream> #include<algorithm> #include<str

Codeforces #Round 376 部分题解

A: 题目传送门:http://codeforces.com/problemset/problem/731/A 直接根据题意模拟即可 1 #include "bits/stdc++.h" 2 3 using namespace std ; 4 typedef long long QAQ ; 5 6 char s[ 1010 ] ; 7 8 inline int Calc ( const char x , const char y ) { 9 if ( x > y ) return

Codeforces Round #467(Div2)题解

凌晨起来打CF,0:05,也是我第一次codeforces 第一题: 我刚开始怀疑自己读错题了,怎么会辣么水. 判除了0的数字种类 #include <cstdio> int n,ans=0; bool hsh[610]; int main(){ scanf("%d",&n);int i; for(i=1;i<=n;++i){ int x;scanf("%d",&x);if(!hsh[x] && x)++ans,hs

Codeforces Round #616 (Div. 1)

Mind Control 题目链接:https://codeforces.com/contest/1290/problem/A 题意: 一共有n件物品,每件物品都有自己的价值. 现有n个人,每个人可以按顺序随机从头或尾拿走一份礼物 其中你排在第m位,并且你可以控制X个人指定他们拿头或尾的礼物 问你最少能拿到多大的价值的物品 分析: 我们令K = min(X , M-1),这是因为你能拿到礼物的价值只会受到前M-1个人影响 此时你前面的K个人可以受你控制,M - 1 - K个人不会受到你的控制,我

codeforces round #616 div2 A (Even but not even)水题

水题: 链接:https://codeforces.com/contest/1291/problem/A 题意:给一个字符数组,删去数组中的一些数,使得剩下的数字的和为偶数,其中的数字有偶数多个奇数且首尾数字为奇数 找两个奇数就满足题意了: 代码: #include <cstdio> #include <iostream> #include <algorithm> #include <cstring> using namespace std; #define

Educational Codeforces Round 16---部分题解

710A. King Moves 给你图中一点求出它周围有几个可达的点: 除边界之外都是8个,边界处理一下即可: #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<cctype> #include<queue> #include<stack> #include<v