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. Python 按分类样本数占比生成并随机获取样本数据

    按分类样本数占比生成并随机获取样本数据 By:授客 QQ:1033553122 开发环境 win 10 python 3.6.5 需求 已知样本分类,每种分类的样本占比数,及样本总数,需要随机获取这些 ...

  2. java中使用jdbc连接数据库操作

    先贴代码,在做说明 import java.sql.*; import java.util.ArrayList; import java.util.List; public class Conn { ...

  3. 释放资源的方式try-with-resources

    1.try-catch-finally 2.try-with-resources 使用方法 try(//这里定义你要使用的资源){} catch(){} 注意:try()里只能存放流对象(资源对象), ...

  4. 【Maxwell】03 定向监听&全量输出

    一.定向监听 定向监听,即只监听某一个特定的表,或者库 1.创建样本案例 -- 创建监听的库(演示样本) CREATE DATABASE `test-db-2` CHARACTER SET 'utf8 ...

  5. obs 直播软件 虚拟摄像头插件 —— obs-virtualcam

    如题: 外网下载地址: https://github.com/Fenrirthviti/obs-virtual-cam/releases 这个东西是做啥用的这里就不讲了,这个东西的资源不好找,找了好半 ...

  6. 【EF Core】自动生成的字段值

    自动生成字段值,咱们首先想到的是主键列(带 IDENTITY 的主键).EF Core 默认的主键配置也是启用 Identity 自增长的,而且可以自动标识主键.前提是代表主键的实体属性名要符合以下规 ...

  7. 解决 jquery attr多次使用失效的问题

    今天做一个全选功能的时候用到了jq 的attr 的方法,可是在真正使用的时候首次是可以实现全选和全不选的功能,然而 多点几次就会发勾选的效果消失了!先看下代码吧: <!DOCTYPE html& ...

  8. 被怼了:acks=all消息也会丢失?

    消息队列是面试中一定会被问到的技术模块,虽然它在面试题占比不及并发编程和数据库,但也属于面试中的关键性问题.所以今天我们就来看一道,MQ 中高频,但可能会打破你以往认知的一道面试题. 所谓的关键问题指 ...

  9. 武汉市委郭元强书记、盛阅春代市长会见白鲸开源CEO郭炜等嘉宾代表

    2024年6月14日,第二届软件创新发展大会在中国武汉举行.大会云集了来自全国的书数百位院士.专家.知名软件企业负责人,包括中国工程院院士倪光南.中国科学院院士陈十一.国家工业信息安全发展研究中心总工 ...

  10. 018.CentOS升级内核

    一 更新yum源 1 [root@localhost ~]# rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org 2 [root@lo ...