首页 > 其他分享 >『模拟赛』CSP-S模拟12

『模拟赛』CSP-S模拟12

时间:2024-10-18 21:36:53浏览次数:1  
标签:ch int st hh 12 fo CSP 模拟 define

Rank

有点烂

image

A. 小 h 的几何

虽然但是看起来这就是签。赛时看到计算几何直接润了,没看到送的 20pts。

主要问题在证一个结论:九点圆圆心位于垂心和外心的中点。几何证法见此,用到的全是初中知识,很好懂。证完就很水了,圆心即为 \(\frac{A+B+C}{2}\),随便算个选中的方案数再乘上总概率就完了。系数是 \(\frac{(n-1)(n-2)}{2}\times \frac{6}{n(n-1)(n-2)}=\frac{3}{n}\)。复杂度线性。

点击查看代码
#include<bits/stdc++.h>
#define fo(x, y, z) for(register int (x) = (y); (x) <= (z); (x)++)
#define fu(x, y, z) for(register int (x) = (y); (x) >= (z); (x)--)
using namespace std;
typedef long long ll;
#define lx ll
inline lx qr()
{
	char ch = getchar();lx x = 0 , f = 1;
	for(;ch<'0'||ch>'9';ch = getchar()) if(ch == '-') f = -1;
	for(;ch>= '0' && ch<= '9';ch = getchar()) x = (x<<3) + (x<<1) + (ch^48);
	return x*f;
}
#undef lx
#define qr qr()
#define pii pair<int, int>
#define M_P(a, b) make_pair(a, b)
#define fi first
#define se second
#define P_B(x) push_back(x)
const int Ratio = 0;
const int N = 5e5 + 5, M = 5e5;
const int mod = 998244353;
const double pai = 3.1415926535897932384626;
int n;
double ansx, ansy;
namespace Wisadel
{
    short main()
    {
        freopen("geometry.in", "r", stdin) , freopen("geometry.out", "w", stdout);
        n = qr;
        fo(i, 1, n)
        {
            double a; cin >> a;
            a = (a * pai) / (1.0 * 1e9);
            ansx += cos(a) * 3 / (2.0 * n);
            ansy += sin(a) * 3 / (2.0 * n);
        }
        printf("%.11lf %.11lf\n", ansx, ansy);
        return Ratio;
    }
}
signed main(){return Wisadel::main();}

B. 小 w 的代数

一直以为这道是签,特殊性质狂挂,只有 20pts,寄。

正解果然是树形 dp,用到了圆方树优化,圆点统计方点转移。设 \(f_{i,j}\) 表示到点 \(i\) 链尾为 \(j\) 的方案数。发现在链上是好转移的,考虑怎么在环上转移。我们可以拆环成链,在这道题上体现就是顺逆时针分别考虑,二者只会在进入的点的答案上重复统计,其余由于顺序不同方案都是不交的。然后就做完了,复杂度是 \(\mathcal{O(n^3)}\) 的,不是很优但足够通过本题。

然后就是由这道题发现的小知识。Tarjan 求点双时,判断形成点双的条件写 low[v] >= dfn[u] 是一定对的,而如果判断条件写了取等,则一定不能判掉由父亲过来的边,即不能写 if(v == fa) continue;。证明很好证,简单手模就出来了。

点击查看代码
#include<bits/stdc++.h>
#define fo(x, y, z) for(register int (x) = (y); (x) <= (z); (x)++)
#define fu(x, y, z) for(register int (x) = (y); (x) >= (z); (x)--)
using namespace std;
typedef long long ll;
#define lx ll
inline lx qr()
{
	char ch = getchar();lx x = 0 , f = 1;
	for(;ch<'0'||ch>'9';ch = getchar()) if(ch == '-') f = -1;
	for(;ch>= '0' && ch<= '9';ch = getchar()) x = (x<<3) + (x<<1) + (ch^48);
	return x*f;
}
#undef lx
#define qr qr()
#define pii pair<int, int>
#define M_P(a, b) make_pair(a, b)
#define fi first
#define se second
#define P_B(x) push_back(x)
const int Ratio = 0;
const int N = 2e5 + 5, M = 5e5;
const int mod = 998244353;
int n, m, tot;
int dfn[N], low[N], dt;
int hh[N], to[N << 1], ne[N << 1], cnt;
int f[1005][1005], g[N], s;
ll ans;
vector<int> e[N], zc;
stack<int> st;
namespace Wisadel
{
    void Wadd(int u, int v)
    {
        to[++cnt] = v;
        ne[cnt] = hh[u];
        hh[u] = cnt;
    }
    void Wtarjan(int u, int fa)
    {
        dfn[u] = low[u] = ++dt, st.push(u);
        for(int i = hh[u]; i != -1; i = ne[i])
        {
            int v = to[i];
            if(v == fa) continue;
            if(!dfn[v])
            {
                Wtarjan(v, u);
                low[u] = min(low[u], low[v]);
                if(low[v] >= dfn[u])
                {
                    tot++;
                    while(st.size())
                    {
                        int zc = st.top(); st.pop();
                        e[zc].P_B(tot), e[tot].P_B(zc);
                        if(zc == v) break;
                    }
                    e[u].P_B(tot), e[tot].P_B(u);
                }
            }
            else low[u] = min(low[u], dfn[v]);
        }
    }
    void Wdfs(int u, int fa)
    {
        if(u <= n)
        {
            fo(i, s, u - 1) ans = (ans + f[u][i]) % mod;
            fo(i, s, u - 1) f[u][u] = (f[u][u] + f[u][i]) % mod;
        }
        else
        {
            int cz = 0, len = e[u].size();
            fo(i, 0, len - 1) if(e[u][i] == fa){cz = i; break;}
            zc.clear();
            for(int i = (cz + 1) % len; i != cz; i = (i + 1) % len) zc.P_B(e[u][i]);
            fo(i, s, n) g[i] = f[fa][i];
            for(int v : zc)
            {
                fo(i, s, n) f[v][i] = (f[v][i] + g[i]) % mod;
                fo(i, s, v - 1) g[v] = (g[v] + g[i]) % mod;
            }
            fo(i, s, n) g[i] = f[fa][i];
            reverse(zc.begin(), zc.end());
            for(int v : zc)
            {
                fo(i, s, n) f[v][i] = (f[v][i] + g[i]) % mod;
                fo(i, s, v - 1) g[v] = (g[v] + g[i]) % mod;
            }
            for(int v : zc) fo(i, s, n)
                f[v][i] = (f[v][i] - f[fa][i] + mod) % mod;
        }
        for(int v : e[u]) if(v != fa) Wdfs(v, u);
    }
    short main()
    {
        freopen("algebra.in", "r", stdin) , freopen("algebra.out", "w", stdout);
        n = qr, m = qr;
        memset(hh, -1, sizeof hh);
        fo(i, 1, m)
        {
            int a = qr, b = qr;
            Wadd(a, b), Wadd(b, a);
        }
        tot = n;
        Wtarjan(1, 0);
        fo(i, 1, n)
        {
            fo(j, 1, n) fo(k, 1, n) f[j][k] = 0;
            f[i][i] = 1;
            s = i;
            Wdfs(i, i);
        }
        ans = (ans + n) % mod;
        printf("%lld\n", ans);
        return Ratio;
    }
}
signed main(){return Wisadel::main();}

C. 小 y 的数论

nt 题面完全看不懂。据 xrlong 所说这是一道集合了诸多板子的题。

D. 小 j 的组合

真正的签。

考虑每次选择点相当于给这个点多一次经过机会,理解了这一点就很好办了。考虑每一个点最后都会回到首尾这一条链上,那么首尾链最长时可得加点次数最少。这又是一棵树,因此问题就变成了求树的直径。范围很小,直接 Floyd 求就行。然后 dfs 模拟跑一遍即可。不用 Floyd 复杂度大概是线性的,用了 \(\mathcal{O(n^3)}\),\(n\le 100\),影响不大。

点击查看代码
#include<bits/stdc++.h>
#define fo(x, y, z) for(register int (x) = (y); (x) <= (z); (x)++)
#define fu(x, y, z) for(register int (x) = (y); (x) >= (z); (x)--)
using namespace std;
typedef long long ll;
#define lx ll
inline lx qr()
{
	char ch = getchar();lx x = 0 , f = 1;
	for(;ch<'0'||ch>'9';ch = getchar()) if(ch == '-') f = -1;
	for(;ch>= '0' && ch<= '9';ch = getchar()) x = (x<<3) + (x<<1) + (ch^48);
	return x*f;
}
#undef lx
#define qr qr()
#define pii pair<int, int>
#define M_P(a, b) make_pair(a, b)
#define fi first
#define se second
#define P_B(x) push_back(x)
const int Ratio = 0;
const int N = 2e5 + 5, M = 5e5;
int n, tot;
int d[105][105];
int hh[N], to[N << 1], ne[N << 1], cnt;
bool yz[N];
vector<int> ans;
namespace Wisadel
{
    void Wadd(int u, int v)
    {
        to[++cnt] = v;
        ne[cnt] = hh[u];
        hh[u] = cnt;
    }
    void Wdfs(int u, int tar)
    {
        int zc = 0;
        yz[u] = 1; ans.P_B(u);
        for(int i = hh[u]; i != -1; i = ne[i])
        {
            int v = to[i];
            if(yz[v]) continue;
            if(d[tar][v] + 1 == d[tar][u])
            {
                zc = v;
                continue;
            }
            Wdfs(v, tar);
            printf("%d ", u);
            ans.P_B(++tot);
        }
        if(zc) Wdfs(zc, tar);
    }
    short main()
    {
        freopen("combo.in", "r", stdin) , freopen("combo.out", "w", stdout);
        n = qr;
        memset(hh, -1, sizeof hh);
        fo(i, 1, n) fo(j, i + 1, n) d[i][j] = d[j][i] = 1e9;
        fo(i, 1, n - 1)
        {
            int a = qr, b = qr;
            d[a][b] = d[b][a] = 1;
            Wadd(a, b), Wadd(b, a);
        }
        tot = n;
        fo(k, 1, n) fo(i, 1, n) fo(j, 1, n)
            d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
        int st = 1, ed = 1;
        fo(i, 1, n) fo(j, i + 1, n) if(d[i][j] > d[st][ed]) st = i, ed = j;
        printf("%d\n", n - d[st][ed] - 1);
        Wdfs(st, ed); puts("");
        for(int i : ans) printf("%d ", i);puts("");
        return Ratio;
    }
}
signed main(){return Wisadel::main();}

感觉一天打的好一天打得烂?然后中午和 CTH 浅算一下发现 CSP 和 NOIP 都是烂的那天?

CTH:你停一天不就行了。

感觉非联考的题好有水平啊,每次都有几个挺毒瘤的。

起码学了学圆方树,不知道九点圆等到回归 whk 后有没有机会用,不过学了总是好的。

明后天据说有 \(n\) 场比赛要打,模拟赛,ATCoder,CF,STAOI。。。到时候看改题情况决定打不打吧。


完结撒花!

艾雅法拉~

image

标签:ch,int,st,hh,12,fo,CSP,模拟,define
From: https://www.cnblogs.com/Ratio-Yinyue1007/p/18475080

相关文章

  • csp-s模拟12
    题面首先,这些题目的题意就不太好理解A利用三个中点,暴力就是暴力算斜率暴力算交点圆周率别再写错了constdoublePi=acos(-1);点击查看代码#include<bits/stdc++.h>#definespeed()ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);#definelllonglong#definepb......
  • 通过比较list与vector在简单模拟实现时的不同进一步理解STL的底层
     cplusplus.com/reference/list/list/?kw=list当我们大致阅读完list的cplusplus网站的文档时,我们会发现它提供的接口大致上与我们的vector相同。当然的,在常用接口的简单实现上它们也大体相同,但是它们的构造函数与迭代器的实现却大有不同。(食用本文时建议与文末的模拟实现代......
  • ZROI-21-CSP7连-DAY 7 T2
    题面挂个pdf题面下载算法有点像扫描线?容易想到离散化坐标点,那么对于离散化之后的坐标\(x\),粗略来看,其能分开区间的个数即为\(\displaystyle\sum_{i=1}^{n}\left[{l_i<x<R_i}\right]\)这个可以用类似于差分的方法解决,每次对于一个区间\(\left(l_i,r_i\r......
  • 10.18 模拟赛
    炼石计划10月04日NOIP模拟赛#8【补题】-比赛-梦熊联盟(mna.wang)复盘T1有种div.2B的风格,没秒,想看题。T2。只判是否无解?\(k\le100\)?把\(200\)个关键连通块拿出来建图跑传递闭包不就做完了。一遍过大样例?简直不可思议,但还是把T2关了吧。用分析CF题的方......
  • 2024.10.18模拟赛反思
    2024.10.18模拟赛反思感觉今天状态不太好,整个人比较恍惚。早自习我都不知道在干什么,考试的时候脑子里也是一团糨糊(晚上提前到\(12\)点睡觉,结果状态更差了)。首先是\(T1\),开始我以为简单无向连通图的“简单”是指的仙人掌,所以想了一个点双的做法。写到一半发现做法复杂了,用最小......
  • 【信奥赛·C++基础语法】CSP-J C++ 指针与引用
    序言指针和引用是非常重要的概念,它们提供了对内存的直接访问和操作方式,使得程序员能够更加灵活地处理数据哈,理解指针和引用的工作原理以及正确使用它们,对于编写高效、安全的C++程序至关重要。一、指针的基本概念指针的定义和作用指针是一个变量,它存储了另一个变量的内......
  • [49 & 50] (多校联训) A层冲刺NOIP2024模拟赛08 | CSP-S 模拟 12
    一小孩在奶茶店玩封盖机被绞断四根手指记者:你现在感觉怎么样小孩:......
  • csp-s模拟12
    csp-s模拟12\(T1\)T2918.小h的几何\(100pts\)对于任意三角形,均有其三条边的中点、三条高的垂足、三个顶点与垂心连线的中点,这九个点在一个圆上。观察样例可知,对于单位圆上\(\triangleABC\)的三个顶点\(A(x_{a},y_{a}),B(x_{b},y_{b}),C(x_{c},y_{c})\),其九点圆......
  • csp-s模拟12
    又双叒叕垫底啦!!!rank22,T10,T220,T30,T430。逆天模拟赛,逆天题面,怕你赛场上不会打暴力真是煞费苦心出了一场暴力专场。小h的几何高斯消元求圆心精度被卡炸了,乐了。咋还考向量啊,不学文化课,输了。九点圆的圆心是外心\(O\)和垂心\(H\)的中点,且\(\overrightarrow{OH}=\overrightar......
  • P5690 [CSP-S2019 江西] 日期 &&P7909 [CSP-J 2021] 分糖果 &&P5657 [CSP-S2019] 格雷
    今天继续懒惰,继续三合一!!![CSP-S2019江西]日期题目背景CSP-SJX2019T1题目描述Alice在纸上写下了一个日期,形式为\(\text{MM-DD}\),其中\(\text{MM}\)与\(\text{DD}\)都是两位数字,分别表示月和天,然而这个日期并不一定存在。Alice找来了Bob要他更改若干位上的数字,使得这个......