0
点赞
收藏
分享

微信扫一扫

2.9模拟总结

云竹文斋 2022-02-10 阅读 30
算法

文章目录

前言

180pts
30+50+100
rnk10

题目比较简单的一场考试。
不太满意。
T3是做过的原题,切了不算啥本事,而且还花了1.5h
T1、2都只混了个暴力分,有点惨。

题目解析

序列计数(sequence)

耳目一新的莫队题。
就是没想到…
由于T3整了太长时间,后来又先去了T2,这题从10:30才开始摸,做的时候时间不是很够了。
一开始就写个 ∑ \sum 然后开始化。
从那一刻我这道题几乎就已经没了,后来一直在各种NTT,甚至还想到了NTT配合分块这种诡异的东西。
不要先入为主!
当一个思路不断的转化后遇到一个难以解决的问题时,不一定要在这个问题上死磕,也应该试试推翻之前的思路,从新审视一下这个题。
既然有组合数,也不是没想过杨辉三角,但是几乎只在大脑里存在了一瞬间…

S ( x , y ) = ∑ i = 0 x C y i S(x,y)=\sum_{i=0}^xC_y^i S(x,y)=i=0xCyi
( l , r , x ) (l,r,x) (l,r,x) 的答案就是 S ( r , x ) − S ( l − 1 , x ) S(r,x)-S(l-1,x) S(r,x)S(l1,x)
考虑如何移动 x , y x,y x,y 指针。
(虽然依然有 x ≤ y x\le y xy,但叫它左右指针还是不太贴切了)
S ( x , y + 1 ) = S ( x , y ) + C y + 1 x S(x,y+1)=S(x,y)+C_{y+1}^x S(x,y+1)=S(x,y)+Cy+1x
S ( x , y − 1 ) = S ( x , y ) − C y x S(x,y-1)=S(x,y)-C_y^x S(x,y1)=S(x,y)Cyx
S ( x + 1 , y ) = 2 × S ( x , y ) − C y x S(x+1,y)=2\times S(x,y)-C_y^x S(x+1,y)=2×S(x,y)Cyx
S ( x − 1 , y ) = S ( x , y ) + C y x − 1 2 S(x-1,y)=\frac{S(x,y)+C_y^{x-1}}{2} S(x1,y)=2S(x,y)+Cyx1
前两个显然,第三个想想杨辉三角的转移即可得,第四个是第三个的逆过程。
然后就做完了。

T2 网格选点(grid)

怎么又是grid
本次考试可以说主攻的一道题。
可以说,题解PPT里的每行字我考场几乎都推出来了。
然后呢?
然后呢!
这个玩意证出来反向单调之后咋办啊…
上完线段树这个东西变得很难搞,每个点都转移区间都不一样。
现在也不知道怎么实现…

不过这个题单调性是推出来的而不是“感性理解”的,也算是一个突破吧

T3 孤立点集(isolated)

见到这个原题我是一点也不高兴。
当时我就被这个毒瘤东西恶心坏了。
但是毕竟是原题,还是最先做的。
(努力调用内存…)
差不多想起来了做法,但是忘记为什么可以这么做了…
然后发现自己第三问连怎么做也忘记了…
想了好久想起来可以暴力删点(与其说是想起来了不如说是做出来了)。
代码写起来不太难,匈牙利还是很香的,比dinic好写不知道多少,考场能用还是要用。
但是前前后后还是花了1.5h…

当时我做这个题的时候就是似懂非懂的,难怪如今再做的时候困难。
需要用一个 dilworth 定理,当时好像我根本就没理解这个定理。

代码

T1

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define ok debug("OK\n")
inline ll read(){
	ll x(0),f(1);char c=getchar();
	while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}
	while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
	return x*f;
}
const int N=4e5+100;
const int B=150;
const int inf=1e9;
const int mod=998244353;

int n,m;
int o=2e5,w;
inline ll ksm(ll x,ll k){
	ll res(1);
	while(k){
		if(k&1) res=res*x%mod;
		x=x*x%mod;
		k>>=1;
	}
	return res;
}
ll jc[N],ni[N];
int bel[N];
void init(){
	int n=o;
	w=sqrt(n);
	jc[0]=1;
	for(int i=1;i<=n;i++) jc[i]=jc[i-1]*i%mod;
	ni[n]=ksm(jc[n],mod-2);
	for(int i=n-1;i>=0;i--) ni[i]=ni[i+1]*(i+1)%mod;
	for(int i=1;i<=n;i++) bel[i]=(i-1)/w+1;
	//for(int i=1;i<=n;i++) printf("i=%d bel=%d\n",i,bel[i]);
	return;
}
inline ll C(int n,int m){
	return jc[n]*ni[m]%mod*ni[n-m]%mod;
}
int L,R;
struct query{
	int x,y,id,op;
	bool operator < (const query oth)const{
		if(bel[x]!=bel[oth.x]) return bel[x]<bel[oth.x];
		else{
			if(bel[x]&1) return y<oth.y;
			else return y>oth.y;
		}
	}
}q[N];
int ans[N],tot;
int x,y;
ll now;
int clo;
inline ll calc(int nx,int ny){
	while(nx<x) now=(now-C(y,x--)+mod)%mod,++clo;		
	while(nx>x) now=(now+C(y,++x))%mod,++clo;
	while(ny>y) now=(now*2-C(y++,x)+mod)%mod,++clo;
	while(ny<y) now=((now+C(--y,x))*ni[2])%mod,++clo;
	//printf("x=%d y=%d calc=%lld\n",x,y,now);
	return now;
}

signed main(){
	freopen("sequence.in","r",stdin);
	freopen("sequence.out","w",stdout);
	//freopen("a.in","r",stdin);
	//freopen("a.out","w",stdout);
	n=read();
	init();
	for(int i=1;i<=n;i++){
		int l=read(),r=read(),x=read();
		q[++tot]=(query){l-1,x,i,-1};
		q[++tot]=(query){r,x,i,1};
	}
	sort(q+1,q+1+tot);
	//x=1,y=0;
	now=1;
	for(int i=1;i<=tot;i++){
		ans[q[i].id]=(ans[q[i].id]+q[i].op*calc(q[i].x,q[i].y)+mod)%mod;
		//printf("(%d %d) clock=%d\n",q[i].x,q[i].y,clo);
	}
	for(int i=1;i<=n;i++) printf("%d\n",ans[i]);
	//printf("clock=%d\n",clo);
	return 0;
}
/*
3
5 3 2
1 2 0
*/
 

T2

暂无qwq
但我可以把暴力贴过来

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define ok debug("OK\n")
inline ll read(){
	ll x(0),f(1);char c=getchar();
	while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}
	while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
	return x*f;
}
const int N=2e5+100;
const int B=920;
const int inf=1e9;
const int mod=998244353;

int n,m;
struct node{
	int x,y;
	bool operator < (const node oth)const{return x<oth.x;}
}p[N];
int f[N];
ll x[N],y[N];
ll dp[N];

signed main(){
	freopen("grid.in","r",stdin);
	freopen("grid.out","w",stdout);
	n=read();m=read();
	for(int i=1;i<=n;i++) p[i].x=read(),p[i].y=read();
	sort(p+1,p+1+n);
	for(int i=1;i<=n;i++) x[i]=p[i].x,y[i]=p[i].y;
	int mx(0);
	ll ans=2e18;
	for(int i=1;i<=n;i++){
		f[i]=1;
		for(int j=1;j<i;j++){
			if(y[j]<y[i]) f[i]=max(f[i],f[j]+1);
		}
		mx=max(mx,f[i]);
	}
	for(int i=1;i<=n;i++){
		if(f[i]==1) dp[i]=x[i]*y[i];
		else dp[i]=2e18;
		for(int j=1;j<i;j++){
			if(f[i]==f[j]+1&&y[j]<y[i]){
				dp[i]=min(dp[i],dp[j]+(x[i]-x[j])*(y[i]-y[j]));
			}
		}
		if(f[i]==mx) ans=min(ans,dp[i]+(m-x[i])*(m-y[i]));
	}
	printf("%lld\n",ans);
	return 0;
}
/*
5 2
2 4
1 5
1 2
2 3
3 4
3 5
*/
 

T3

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define ok debug("OK\n")
inline ll read(){
	ll x(0),f(1);char c=getchar();
	while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}
	while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
	return x*f;
}
const int N=230;
const int B=920;
const int inf=1e9;
const int mod=998244353;

int n,m;
struct node{
	int to,nxt;
}p[N*N*2];
int fi[N],cnt;
inline void addline(int x,int y){
	p[++cnt]=(node){y,fi[x]};fi[x]=cnt;
}

int mat[N],vis[N],tim;
int f[N][N],ban[N];
bool find(int x){
	if(ban[x]) return false;
	if(vis[x]==tim) return false;
	vis[x]=tim;
	for(int i=fi[x];~i;i=p[i].nxt){
		int to=p[i].to;
		if(ban[to]) continue;
		if(!mat[to]||find(mat[to])){
			mat[x]=to;mat[to]=x;
			return true;
		}
	}
	return false;
}
int hangry(){
	memset(mat,0,sizeof(mat));
	memset(vis,0,sizeof(vis));
	int res(0);
	for(int i=1;i<=n;i++) tim=i,res+=find(i);
	//for(int i=1;i<=n;i++) printf("i=%d mat=%d\n",i,mat[i]?mat[i]-n:0);
	//printf("match=%d\n",res);
	return res;
}
int tag[N];
void dfs(int x){
	if(tag[x]) return;
	tag[x]=1;
	for(int i=fi[x];~i;i=p[i].nxt){
		int to=p[i].to;
		tag[to]=1;
		assert(mat[to]);
		dfs(mat[to]);
	}
}

signed main(){
	freopen("isolated.in","r",stdin);
	freopen("isolated.out","w",stdout);
	n=read();m=read();
	memset(fi,-1,sizeof(fi));cnt=-1;
	for(int i=1;i<=m;i++){
		int x=read(),y=read();
		f[x][y]=1;
	}
	for(int k=1;k<=n;k++){
		for(int i=1;i<=n;i++){
			for(int j=1;j<=n;j++) f[i][j]|=(f[i][k]&f[k][j]);
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			if(f[i][j]) addline(i,j+n),addline(j+n,i);//printf("(%d %d)\n",i,j);
		}
	}
	int ans=n-hangry();
	printf("%d\n",ans);
	//ans=n-hangry();
	//printf("%d\n",ans);
	for(int i=n+1;i<=n+n;i++) if(!mat[i]) dfs(i);
	for(int i=1;i<=n;i++){
		if(tag[i+n]&&!tag[i]) printf("1");
		else printf("0");
	}
	puts("");
	for(int i=1;i<=n;i++){
		memset(ban,0,sizeof(ban));
		int S(0);
		for(int x=1;x<=n;x++) if(i==x||f[x][i]||f[i][x]) ban[x]=ban[x+n]=1,++S;
		int res=n-S-hangry()+1;
		//printf("res=%d\n",res);
		if(res==ans) printf("1");
		else printf("0");
	}
	return 0;
}
/*
5 2
2 4
1 5
1 2
2 3
3 4
3 5
*/
 

总结

做题有的时候真的挺随缘的。
T1想到了一下就通了,想不到就是想不到。
还有T2这种,临门一脚就是射不出去,真心挺郁闷的。
还是太弱了,榜上那几个大佬总是屹立不倒的。
见到这种可离线互相独立的询问就应该多少想一想莫队。
还有,不能在一个思路吊死,思路打开。
明天加油吧!awa

举报

相关推荐

2.9日学习总结

2.16模拟总结

2.7模拟总结

2.9 权限管理

2.9(Clear Cold Water)

2022.3.14模拟赛总结

2.9_tree_树

0 条评论