A 奇观

考虑到 CCF 可以拆开算,答案为 \((ans_c)^2\times ans_f\)

剩下的东西比较少,考虑 DP

我的 dp 是从爆搜改的,设 \(f_{i,j}\) 表示递归到第 \(i\) 层时 \(j\) 的方案数,原始的爆搜代码如下:

int dfs_f2(int now,int id){
if(now==0) return 1;
if(now==1) return f_c[0][id];
if(f_c[now][id]) return f_c[now][id];//cth<<"dfs "<<now<<" "<<id<<endl;
int res=0;
if(now!=2){
for(int i=1;i<=n;++i){
if(i!=id and hdk.find(i,id)){
res+=dfs_f2(now-1,i);
res%=p;
}
}
}
else{
for(int i=1;i<=n;++i){
if(i!=id and hdk.find(i,id)){
res+=f_c[0][i]*f_c[0][id];
res%=p;
}
}
}
return f_c[now][id]=res%p;
}

可以发现该搜索的最大问题在于内层枚举时的循环,注意到此题是完全图删边形成的,因此考虑做容斥,用总方案数减去不合法的,不合法的可以通过枚举得到

我写的 dp 比较异端,看个乐子就行

    scanf("%lld %lld",&n,&m);
for(int i=1;i<=n;++i){
f_c[0][i]=n-1;
}
for(int i=1;i<=m;++i){
int x,y;scanf("%lld %lld",&x,&y);
del_e[x].push_back(y);
del_e[y].push_back(x);
f_c[0][x]--;f_c[0][y]--;
}
int sum=0;
for(int i=1;i<=n;++i){
sum=(sum+f_c[0][i])%p;
}
for(int i=1;i<=n;++i){
f_c[1][i]=fixed(sum-f_c[0][i]);
for(int j:del_e[i]) f_c[1][i]=fixed(f_c[1][i]-f_c[0][j]);
}
sum=0;
for(int i=1;i<=n;++i){
sum=(sum+f_c[1][i])%p;
}
for(int i=1;i<=n;++i){
f_c[2][i]=fixed(sum-f_c[1][i]);
for(int j:del_e[i]) f_c[2][i]=fixed(f_c[2][i]-f_c[1][j]);
}
sum=0;
for(int i=1;i<=n;++i){
sum=(sum+f_c[2][i])%p;
}
int c=sum%p;
memset(f_c[1],0,sizeof f_c[1]);
memset(f_c[2],0,sizeof f_c[2]);
memset(f_c[3],0,sizeof f_c[3]);
sum=0;
for(int i=1;i<=n;++i){
sum=(sum+f_c[0][i])%p;
}
for(int i=1;i<=n;++i){
f_c[1][i]=fixed((sum-f_c[0][i])*f_c[0][i]);
for(int j:del_e[i]){
f_c[1][i]=fixed(f_c[1][i]-f_c[0][j]*f_c[0][i]);
}
}
sum=0;
for(int i=1;i<=n;++i){
sum=(sum+f_c[1][i])%p;
}
for(int i=1;i<=n;++i){
f_c[2][i]=fixed(sum-f_c[1][i]);
for(int j:del_e[i]){
f_c[2][i]=fixed(f_c[2][i]-f_c[1][j]);
}
}
int f=0;
for(int i=1;i<=n;++i){
f=(f+f_c[2][i])%p;
}
cout<<fixed(c*c%p*f)<<endl;

B 铁路

非常好的题

注意到我们没有必要非得去给每次操作新建边,我们可以直接在树上跳 lca 来用并查集合并,这样能解决我们求节点数目的问题:每进行一次操作,节点数加一,并查集上每进行一次合并,节点数减一

然后考虑怎么优化这个过程,注意到,已经在同一个并查集里的数是不需要合并的,因此我们可以借助并查集维护相关信息来直接跳过这段并查集,那么维护什么东西能快速跳节点呢,因为我们是在向根跳,因此我们直接维护并查集中深度最小的节点编号就好了,维护的时候直接往深度最小的节点跳。有人会问这么跳,万一跳过头了怎么办,其实无所谓,因为既然你能跳过头,说明你的目标节点一定在当前并查集内,直接判断当前点和目标点是否在同一并查集内即可

随后我们需要解决新建节点的问题,因为我们并没有真的新建节点,那么如果它询问我们一个新的节点编号,我们要知道往哪里去找。这是很好办的,因为新建节点的下属节点一定已经被合并在同一个并查集里了,因此我们直接维护一个下标,存储每一个新建节点对应的并查集的深度最小的点就行了

#include<bits/stdc++.h>
using namespace std;
#define io_h
// #include"./include/hdk/lib.h"
namespace reader{
template<typename T>
inline void read(T& x){
x=0;bool sym=0;char c=getchar();
while(!isdigit(c)){sym^=(c=='-');c=getchar();}
while(isdigit(c)){x=x*10+c-48;c=getchar();}
if(sym)x=-x;
}
template<size_t N>
inline void read(char (&str)[N]){
size_t n=0;char c=getchar();
while(n<N-1&&!isspace(c)){str[n]=c;c=getchar();++n;}
str[n]=0;
}
template<typename T,typename... Args>
inline void read(T& x,Args&... args){
read(x);read(args...);
}
}
int deep[1000001];
using namespace reader;
template<int size>
struct dsu{
int fa[size+1],minn[size+1];
void clear(int n){
for(int i=1;i<=n;++i){
fa[i]=i;
minn[i]=i;
}
}
int find(int id){
if(id==fa[id]){
return id;
}
fa[id]=find(fa[id]);
return fa[id];
}
void join(int x,int y){
int fx=find(x),fy=find(y);
if(fx!=fy){
fa[fx]=fy;
if(deep[fx]>deep[fy]){
minn[fx]=minn[fy];
}
}
}
};
int n,m;
int fa[1000001];
dsu<(int)1e6>d;
int ans=0;
int to[1000001];
void join(int x,int y,int newid){
// cout<<"join "<<x<<" "<<y<<endl;
int ori=x;
while(x!=y){
// cout<<"... "<<x<<" "<<y<<"("<<deep[x]<<","<<deep[y]<<")"<<endl;
if(d.find(x)!=x){
// cout<<"find x("<<x<<")!="<<d.find(x)<<endl;
x=d.minn[d.find(x)];
continue;
}
if(d.find(y)!=y){
// cout<<"find y("<<y<<")!="<<d.find(y)<<endl;
y=d.minn[d.find(y)];
continue;
}
if(deep[x]>deep[y]){
d.join(x,fa[x]);
ans--;
x=fa[x];
}
else{
d.join(y,fa[y]);
ans--;
y=fa[y];
}
}
to[newid]=ori;
}
vector<int>e[500001];
void dfs(int now,int last){
fa[now]=last;
deep[now]=deep[last]+1;
for(int i:e[now]){
if(i!=last){
dfs(i,now);
}
}
}
int main(){
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
read(n,m);
d.clear(n+m);
for(int i=1;i<=n-1;++i){
int x,y;read(x,y);
e[x].push_back(y);
e[y].push_back(x);
}
dfs(1,0);
for(int i=1;i<=m;++i){
int x,y;read(x,y);
if(x>n) x=to[x];
if(y>n) y=to[y];
join(x,y,n+i);
cout<<n+ans<<endl;
}
}

C.光纤

非常不好的题

旋转卡壳是好的,就是给你一个凸包,让你维护凸包直径,也就是一条直线到凸包内所有节点的最大距离最小

有一个结论,这样的直线一定与凸包的某一条边平行,所以你只需要绕着凸包转一圈就能搞定这个问题

问题是怎么确定凸包上哪个点到这条直线距离最大,有一个显然的 \(n^{2}\) 做法

但实际上不是的,因为这个决策点也有单调性,所以开一个双指针就做完了

这题不好,唐诗有理数类

一开始用的平面向量求点线距做的,后来调不出来了,所以改叉积了

#include<bits/stdc++.h>
using namespace std;
#define int __int128
#define abs(x) (x>=0?x:-x)
void _print(__int128 x,bool first=true){
if(x<0){
putchar('-');
_print(-x,false);
return;
}
if(x==0){
if(first) putchar('0');
return;
}
_print(x/10,false);
putchar((int)(x%10)+'0');
}
namespace reader{
template<typename T>
inline void read(T& x){
x=0;bool sym=0;char c=getchar();
while(!isdigit(c)){sym^=(c=='-');c=getchar();}
while(isdigit(c)){x=x*10+c-48;c=getchar();}
if(sym)x=-x;
}
template<size_t N>
inline void read(char (&str)[N]){
size_t n=0;char c=getchar();
while(n<N-1&&!isspace(c)){str[n]=c;c=getchar();++n;}
str[n]=0;
}
template<typename T,typename... Args>
inline void read(T& x,Args&... args){
read(x);read(args...);
}
}
using namespace reader;
class frac{
private:
int z,m;
public:
frac(int x=0,int y=1){
z=x,m=y;
fixed();
}
frac fixed(){
int gcd=__gcd(abs(z),abs(m));
if(m<0){
m*=-1;z*=-1;
}
if(z==0){
m=1;return *this;
}
if(gcd==0) return *this;
z/=gcd;m/=gcd;
return *this;
}
frac upside(){
return frac(m,z);
}
frac operator = (pair<int,int>A){
z=A.first;m=A.second;fixed();
return *this;
}
frac operator + (frac A){
return (frac(z*A.m+m*A.z,m*A.m)).fixed();
}
frac operator * (frac A){
// cout<<"multi ";this->print();putchar(' ');
// A.print();putchar('=');
int gcd1=__gcd(z,A.m);
int gcd2=__gcd(A.z,m);
frac ans=(frac((z/gcd1)*(A.z/gcd2),(m/gcd2)*(A.m/gcd1))).fixed();
// ans.print();putchar('\n');
return ans;
}
frac operator / (frac A){
return (*this*A.upside()).fixed();
}
frac operator -(){
return frac(-z,m);
}
frac operator -(frac A){
return *this+(-A);
}
bool operator <(frac A){
return z*A.m<A.z*m;
}
bool operator ==(frac A){
return z*A.m==A.z*m;
}
bool operator >(frac A){
return !(*this==A and *this<A);
}
void print(){
fixed();
_print(z);putchar('/');_print(m);
// cout<<z<<"/"<<m<<endl;
}
frac _abs(){
return frac(abs(z),abs(m));
}
long double it(){
return z*1.0/m;
}
};
int n;
int q[1000001],top;
int q1[1000001],top1;
struct node{
__int128 x,y;
}d[1000001],sta[1000001];
#define K(i,j) ((double)(d[j].y-d[i].y)/(d[j].x-d[i].x))
int cha(int x,int y,int z){
return (d[y].x-d[x].x)*(d[z].y-d[x].y)-(d[y].y-d[x].y)*(d[z].x-d[x].x);
}
int len(int x,int y){
return (d[y].x-d[x].x)*(d[y].x-d[x].x)+(d[y].y-d[x].y)*(d[y].y-d[x].y);
}
frac ans;
char anss[1000001];
inline void print(__int128 x){
if(!x)putchar('0');
else{
if(x<0)x=-x,putchar('-');
int cnt=0;
while(x)anss[++cnt]=x%10+'0',x/=10;
for(int i=cnt;i;--i)
putchar(anss[i]);
}
}
signed main(){
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
read(n);
if(n<=2){
ans.print();
return 0;
}
for(int i=1;i<=n;++i){
read(d[i].x,d[i].y);
}
sort(d+1,d+1+n,[](const node&x,const node&y){return x.x==y.x?x.y<y.y:x.x<y.x;});
n=unique(d+1,d+1+n,[](const node&x,const node&y){return x.x==y.x&&x.y==y.y;})-d-1;
for(int i=1;i<=n;++i){
while(top>1 and (K(q[top],i)<=K(q[top-1],q[top]))){
--top;
}
q[++top]=i;
}
for(int i=n;i;--i){
while(top1>1 and K(i,q1[top1])<=K(q1[top1],q1[top1-1]))--top1;
q1[++top1]=i;
}
for(int i=2;i<top1;++i){
q[++top]=q1[i];
}
for(int i=1;i<=top;++i){
sta[i]=d[q[i]];
}
for(int i=1;i<=top;++i){
d[i]=sta[i];
}
int now=1;
for(int i=1;i<=top;++i){
while((now==(i==top?1:i+1))||((abs(cha(now,i,(i==top?1:i+1))))<=(abs(cha((now==top?1:now+1),i,(i==top?1:i+1)))))){
now=(now==top?1:now+1);
}
if(ans==frac(0,1) or ans.it()>(double)cha(now,i,(i==top?1:i+1))*cha(now,i,(i==top?1:i+1))/len(i,(i==top?1:i+1))){
ans=frac(cha(now,i,(i==top?1:i+1))*cha(now,i,(i==top?1:i+1)),len(i,(i==top?1:i+1)));
}
}
(ans*frac(1,4)).print();
}

[32](CSP 集训) CSP-S 模拟 3的更多相关文章

  1. 20190820 Tue 集训总结&NOIP模拟 27

    低谷度过了? 但是skyh阿卡了,还是反衬出我的辣鸡. T1知道要sort,却忘了判重,正解不如暴力分高,555. T2成功化出正解柿子,然后化过头了,化出了无法DP的柿子. 果然不够强,大神们一眼就 ...

  2. CSP -- 运营商内容劫持(广告)的终结者

    缘由 我们公司最近手机端H5 经常受到商户和用户的投诉,说有广告并且导致不能正常进行操作,我们商户自己当然不会加广告了,但是商户和用户可不管这些了,就认为是我们的问题 探索发现根本 目前我们用的很多浏 ...

  3. 【密码学】CSP的概念

    CSP加密服务提供者(Cryptographic Service Provider)具有一下几个特点: CSP是真正执行密码运算的独立模块 物理上一个CSP由两部分组成:一个动态连接库,一个签名文件 ...

  4. 【转】密码学 :CSP的概念

    转:[密码学]CSP的概念 CSP加密服务提供者(Cryptographic Service Provider)具有一下几个特点: CSP是真正执行密码运算的独立模块 物理上一个CSP由两部分组成:一 ...

  5. CSP初赛复习

    初赛复习 初赛一定要过啊,否则付出的那么多都白搭了! while(1) ++csp.rp,++csp.luck,++csp.scores; 历史 2020年开始,除NOIP以外的NOI系列其他赛事(包 ...

  6. Easyswoole的WaitGroup和Csp组件的分析和使用

    Easyswoole的WaitGroup和Csp组件的分析和使用 easyswoole可真是个好名字,只是提供了恰到好处的封装,即使是源码也保持了这样的风格.这种风格不论好坏可能都需要各位适应下,哈哈 ...

  7. 2020 CSP&NOIP 游记

    CSP初赛 CSP初赛 Day -1 早上打了模拟赛,T2寒假正好做过,然而还是还是被踩Orz,郑外NB!.中午出校吃了大盘鸡和拉面,还带回来了三瓶可乐. 初赛知识点看了两页不(看)想(不)看(懂)了 ...

  8. 前端安全配置之Content-Security-Policy(csp)

    什么是CSP CSP全称Content Security Policy ,可以直接翻译为内容安全策略,说白了,就是为了页面内容安全而制定的一系列防护策略. 通过CSP所约束的的规责指定可信的内容来源( ...

  9. DVWA 黑客攻防实战(十五) 绕过内容安全策略 Content Security Policy (CSP) Bypass

    看到标题,是否有点疑惑 CPS 是什么东东.简单介绍一下就是浏览器的安全策略,如果 标签,或者是服务器中返回 HTTP 头中有 Content-Security-Policy 标签 ,浏览器会根据标签 ...

  10. CSP应用开发-CryptAPI函数库介绍

    基本加密函数为开发加密应用程序提供了足够灵活的空间.所有CSP的通讯都是通过这些函数.一个CSP是实现所有加密操作的独立模块.在每一个应用程序中至少需要提供一个CSP来完成所需的加密操作.如果使用多于 ...

随机推荐

  1. [rCore学习笔记 03]配置rCore开发环境

    写在前面 本随笔是非常菜的菜鸡写的.如有问题请及时提出. 可以联系:1160712160@qq.com GitHhub:https://github.com/WindDevil (目前啥也没有 rCo ...

  2. Sysbench 使用总结

    Sysbench使用总结 实践环境 CentOS 7.8 Sysbench 1.0.20 下载地址:https://github.com/akopytov/sysbench/archive/refs/ ...

  3. Dubbo日志链路追踪TraceId选型

    一.目的 开发排查系统问题用得最多的手段就是查看系统日志,但是在分布式环境下使用日志定位问题还是比较麻烦,需要借助 全链路追踪ID 把上下文串联起来,本文主要分享基于 Spring Boot + Du ...

  4. AI/机器学习(计算机视觉/NLP)方向面试复习1

    1. 判断满二叉树 所有节点的度要么为0,要么为2,且所有的叶子节点都在最后一层. #include <iostream> using namespace std; class TreeN ...

  5. vue加载三维模型

    创建项目 我使用的是Vue CLI3,具体创建不再赘述,网上教程很多 下载SuperMap iClient3D for WebGL产品包 链接:http://support.supermap.com. ...

  6. 【Java】 Void 类型

    void 也算一个类型,而且是基本数据类型 和其它数据类型一样提供了对应的包装类Void 每个包装类都提供一个TYPE字节实例,返回对应的原型类实例 public static void main(S ...

  7. Jax计算框架的NamedSharding的reshape —— namedsharding-gives-a-way-to-express-shardings-with-names

    官方文档参考: https://jax.readthedocs.io/en/latest/notebooks/Distributed_arrays_and_automatic_parallelizat ...

  8. 【导师招募】Apache DolphinScheduler 社区又又又入选开源之夏啦!

    很高兴和大家宣布,Apache DolphinScheduler 社区今年再次成功入选入选由中国科学院软件研究所开源软件供应链点亮计划发起的"开源之夏"活动. 入选公示链接:htt ...

  9. 白鲸开源 X SelectDB 金融大数据联合解决方案公布!从源头解决大数据开发挑战

    业务挑战与痛点 随着互联网技术的发展.云计算技术的成熟.人工智能技术的兴起和数字化经济的崛起,数据已成为企业的核心资产.在金融行业中,数字化已成为了支撑各类业务场景的核心力量,包括个人理财.企业融资. ...

  10. 如何让您的 .NET应用程序更智能-- 请参加 8.20 的 .NET Conf -- Focus on AI

    Microsoft 将于 2024 年 8 月 20 日举办免费的 .NET Conf: Focus on AI.该虚拟活动为开发人员提供了如何集成 .NET 和 AI 以增强应用程序开发和用户体验的 ...