190730 CSP-S 2019 模拟

今天考了一场 N O I p NOIp NOIp模拟,然而博主由于太菜又双叒叕爆零啦
伤心.jpg

ball

卡空间差评!!!
标算 n 2 l o g n n^2log_n n2logn拿去跑 4000 4000 4000不是很清楚想表达什么。。。(难道是 C F CF CF的原题???大雾
考虑暴力碾标算。
我们用一个更加优秀奇怪的复杂度去跑。
先把问题转化成求所有三角形最短边的最大值。
然后把 n 2 2 \frac{n^2}2 2n2条边弄出来排序,然后用 b i t s e t bitset bitset拿来维护连通性即可。
时间复杂度 O ( n 2 l o g 2 n + n 3 32 ) O(n^2log_2n+\frac{n^3}{32}) O(n2log2n+32n3)
然而能过,毕竟后面那一坨不满并且前面一坨 s o r t sort sort贼快。
当然如果你足够毒瘤可以学习zxyoi仲式计排
至于博主自己,他去世了。
代码:

#include<bits/stdc++.h>
#define ri register int
using namespace std;
const int rlen=1<<18|1;
inline char gc(){
	static char buf[rlen],*ib,*ob;
	(ib==ob)&&(ob=(ib=buf)+fread(buf,1,rlen,stdin));
	return ib==ob?-1:*ib++;
}
inline int read(){
	int ans=0;
	bool f=1;
	char ch=gc();
	while(!isdigit(ch))f^=ch=='-',ch=gc();
	while(isdigit(ch))ans=((ans<<2)+ans<<1)+(ch^48),ch=gc();
	return f?ans:-ans;
}
const int N=4001;
struct pot{
	int x,y;
	pot(int x=0,int y=0):x(x),y(y){}
	friend inline pot operator+(const pot&a,const pot&b){return pot(a.x+b.x,a.y+b.y);}
	friend inline pot operator-(const pot&a,const pot&b){return pot(a.x-b.x,a.y-b.y);}
	friend inline int operator^(const pot&a,const pot&b){return a.x*b.y-a.y*b.x;}
	inline int mod()const{return x*x+y*y;}
	friend inline bool operator<(const pot&a,const pot&b){return a.x^b.x?a.x<b.x:a.y<b.y;}
}ap[N];
bitset<4001>conn[4001];
struct Node{
	short a,b;
	int dist;
	friend inline bool operator<(const Node&a,const Node&b){return a.dist>b.dist;}
};
int n,fa[N];
vector<Node>q;
Node e[N];
int siz[N],tim[N];
inline int find(int x){return fa[x]^x?fa[x]=find(fa[x]):x;}
int main(){
	n=read();
	for(ri i=1;i<=n;++i){
		ap[i].x=read(),ap[i].y=read();
		for(ri j=i-1;j;--j)q.push_back((Node){i,j,(ap[i]-ap[j]).mod()});
	}
	sort(q.begin(),q.end());
	for(ri i=1;i<=n;++i)fa[i]=i,siz[i]=1;
	for(ri i=0,x,y,up=q.size();i<up;++i){
		x=q[i].a,y=q[i].b;
		if((conn[x]&conn[y]).count())return printf("%.10lf",sqrt(q[i].dist)/2.0),0;
		conn[x].set(y);
		conn[y].set(x);
	}
	return 0;
}

slay

一道比较清真的 N O I p NOIp NOIp容斥,考虑枚举最后一段相同的数来进行容斥即可。
貌似是在考察选手的底层数论知识
注意状态数是 O ( K l o g k ) O(Klogk) O(Klogk)的。
瞎写写就能过了。
代码:

#include<bits/stdc++.h>
#define ri register int
using namespace std;
const int rlen=1<<18|1;
inline char gc(){
	static char buf[rlen],*ib,*ob;
	(ib==ob)&&(ob=(ib=buf)+fread(buf,1,rlen,stdin));
	return ib==ob?-1:*ib++;
}
inline int read(){
	int ans=0;
	char ch=gc();
	while(!isdigit(ch))ch=gc();
	while(isdigit(ch))ans=((ans<<2)+ans<<1)+(ch^48),ch=gc();
	return ans;
}
typedef long long ll;
const int mod=1e9+7;
inline int add(const int&a,const int&b){return a+b>=mod?a+b-mod:a+b;}
inline int dec(const int&a,const int&b){return a>=b?a-b:a-b+mod;}
inline int mul(const int&a,const int&b){return (ll)a*b%mod;}
inline void Add(int&a,const int&b){a=a+b>=mod?a+b-mod:a+b;}
inline void Dec(int&a,const int&b){a=a>=b?a-b:a-b+mod;}
inline void Mul(int&a,const int&b){a=(ll)a*b%mod;}
inline int ksm(int a,int p){int ret=1;for(;p;p>>=1,a=mul(a,a))if(p&1)Mul(ret,a);return ret;}
const int N=5005;
int f[N][N],n,k,C[N],inv[N];
inline void init(const int&up){
	C[0]=inv[1]=1,C[1]=n;
	for(ri i=2;i<=up;++i)inv[i]=mul(inv[mod-mod/i*i],mod-mod/i),C[i]=mul(C[i-1],mul(n-i+1,inv[i]));
}
inline int dfs(int p,int k){
	if(!k)return 1;
	if(p==1)return C[k];
	if(p!=n&&~f[p][k])return f[p][k];
	int ret=0;
	for(ri i=1,g,t;i<=k;++i)t=mul(dfs((g=__gcd(i,p)),k-i),g),(i&1?Add(ret,t):Dec(ret,t));
	Mul(ret,mul(n/p,inv[k]));
	if(p^n)f[p][k]=ret;
	return ret;
}
int main(){
	n=read(),k=read();
	memset(f,-1,sizeof(f));
	init(k);
	cout<<dfs(n,k);
	return 0;
}

quests

一道比较清真的 N O I p NOIp NOIp d p dp dp,考虑用补集转化。

枚举不相交的段数扣掉它们的贡献即可。

考场上没调出来可还行。
代码:

#include<bits/stdc++.h>
#define ri register int
using namespace std;
const int rlen=1<<18|1;
inline char gc(){
	static char buf[rlen],*ib,*ob;
	(ib==ob)&&(ob=(ib=buf)+fread(buf,1,rlen,stdin));
	return ib==ob?-1:*ib++;
}
inline int read(){
	int ans=0;
	char ch=gc();
	while(!isdigit(ch))ch=gc();
	while(isdigit(ch))ans=((ans<<2)+ans<<1)+(ch^48),ch=gc();
	return ans;
}
typedef long long ll;
int mod;
inline int add(const int&a,const int&b){return a+b>=mod?a+b-mod:a+b;}
inline int dec(const int&a,const int&b){return a>=b?a-b:a-b+mod;}
inline int mul(const int&a,const int&b){return (ll)a*b%mod;}
inline void Add(int&a,const int&b){a=a+b>=mod?a+b-mod:a+b;}
inline void Dec(int&a,const int&b){a=a>=b?a-b:a-b+mod;}
inline void Mul(int&a,const int&b){a=(ll)a*b%mod;}
inline int ksm(int a,int p){int ret=1;for(;p;p>>=1,a=mul(a,a))if(p&1)Mul(ret,a);return ret;}
const int N=405,M=160005;
int n,f[N],g[N][N],pw[M];
inline void init(int n){
	for(ri i=1;i<=n;++i)for(ri j=n,len=1;j;--j,++len)
	Add(g[n][i],mul(pw[(len-1)*(len-2)>>1],g[j-1][i-1]));
}
int main(){
	n=read(),mod=read();
	pw[0]=1;
	for(ri i=1;i<=n*n;++i)pw[i]=add(pw[i-1],pw[i-1]);
	g[0][0]=1;
	for(ri i=1;i<=n;++i){
		init(i);
		f[i]=pw[(i+1)*i>>1];
		for(ri j=1;j<i;++j)Dec(f[i],mul(f[j],g[i][j]));
	}
	cout<<f[n];
	return 0;
}

总结

如何做到下一次不爆零???

  1. 注意动态空间
  2. 注意要取模 自闭.jpg
  3. 注意不要迟到
  4. 注意头一天晚上早点睡觉

于是在这场考试爆零之后:

ldxcaicai , division 2 , 0 , -1501 1500 → \rightarrow -1 Became Newbie

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值