ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

noip模拟28[我要玩符卡|我有超能力]

2021-08-02 15:35:39  阅读:153  来源: 互联网

标签:const noip int ll 28 超能力 re ret define


\(noip模拟28\;solutions\)

怎么说呢这个分数并不在我的意料范围之内

哈哈哈其实还不错,就是对于期望这一块,我理解的还是不够好

\(T1\;遗忘之祭仪\)

说白了就是一个\(O(n^4)\)的算法,直接去跑一跑,过程中剪剪枝,然后复杂度就无限接近\(O(n2)\)了

但是这个出题人非常气人,你要特判一下符卡中啥也没有的情况,我就因为这个

浮点数例外

AC_code
#include<bits/stdc++.h>
using namespace std;
#define re register int
const int N=1005;
const int inf=0x3f3f3f3f;
int n,m,nm[N][N],sn;
int a,b,ab[N][N],sa,xf=inf,xs,yf=inf,ys;
int sum;
signed main(){
	int T;scanf("%d",&T);
	while(T--){
		//cout<<T<<endl;
		xf=inf;yf=inf;xs=0;ys=0;
		sn=0;sa=0;
		memset(nm,0,sizeof(nm));
		memset(ab,0,sizeof(ab));
		scanf("%d%d%d%d",&n,&m,&a,&b);
		for(re i=1;i<=n;i++){
			char x[N];
			scanf("%s",x+1);
			for(re j=1;j<=m;j++){
				if(x[j]=='x'){
					nm[i][j]=1,sn++;
				}
			}
		}
		for(re i=1;i<=a;i++){
			char x[N];
			scanf("%s",x+1);
			for(re j=1;j<=b;j++){
				if(x[j]=='x'){
					ab[i][j]=1,sa++;
					xf=min(xf,i);xs=i;
					yf=min(yf,j);
					ys=max(ys,j);
				}
			}
		}
		a=xs-xf+1;b=ys-yf+1;
		if(n<a||m<b||a==0||b==0||sa==0){
			printf("No\n");
			continue;
		}
		for(re i=1;i<=a;i++)
			for(re j=1;j<=b;j++)
				ab[i][j]=ab[i+xf-1][j+yf-1];
		if(sn%sa){
			//cout<<"sb"<<endl;
			printf("No\n");
			continue;
		}
		for(re i=1;i<=n-a+1;i++){
			for(re j=1;j<=m-b+1;j++){
				int flag=0;
				for(re x=1;x<=a;x++){
					for(re y=1;y<=b;y++){
						if(nm[i+x-1][j+y-1]!=ab[x][y]&&ab[x][y]){
							flag=1;break;
						}
					}
					if(flag)break;
				}
				if(flag)continue;
				//sum++;
				for(re x=1;x<=a;x++){
					for(re y=1;y<=b;y++){
						if(ab[x][y])nm[i+x-1][j+y-1]=0;
					}
				}
			}
		}
		int flag=0;
		for(re i=1;i<=n;i++)
			for(re j=1;j<=m;j++)
				if(nm[i][j])flag=1;
		if(flag)printf("No\n");
		else printf("Yes\n");
	}
}

\(T2\;客星璀璨之夜\)

我也知道这是那个最最最经典的小球进洞的题

但是吧,我就是不会,说白了就是傻

仔细想一想的话,你会发现,在这些星星们不断减少的过程中,其实每条路径的长度不变

这其实就可以开始转移没条路径的经过次数的期望了

直接从下面转移就好了,因为你的边是在一点一点的减少的哈哈哈,

就是代码啦,直接手摸一下数据就好了

AC_code
#include<bits/stdc++.h>
using namespace std;
#define re register int
#define ll long long
const int N=3005;
const ll mod=998244353;
ll n,m,a[N*2];
ll f[N][N*2];
ll ksm(ll x,ll y){
	ll ret=1;
	while(y){
		if(y&1)ret=ret*x%mod;
		x=x*x%mod;
		y>>=1;
	}
	return ret;
}
ll ans,jc=1;
signed main(){
	scanf("%lld",&n);m=2*n+1;
	for(re i=1;i<=m;i++)scanf("%lld",&a[i]);
	for(re i=1;i<=n;i++){
		ll fi=ksm(i,mod-2),se=ksm(i*2,mod-2);
		for(re j=2;j<=2*i+1;j++){
			ll num=(i*2+1-j)/2;
			if(j&1)f[i][j]=(f[i-1][j]*num%mod*fi%mod+f[i-1][j-1]*se%mod+f[i-1][j-2]*((i-num)*2-1)%mod*se%mod+se)%mod;
			else f[i][j]=(f[i-1][j]*(num*2+1)%mod*se%mod+f[i-1][j-1]*se%mod+f[i-1][j-2]*((i-num-1))%mod*fi%mod+se)%mod;
		}
	}
	for(re i=2;i<=m;i++){
		ans=(ans+(a[i]-a[i-1])*f[n][i]%mod)%mod;
	}
	printf("%lld",ans);
}

\(T3\;割海成路之日\)

所以这个题的并查集用的极其的妙

首先要维护两个并查集这事,肯定是个人都能想出来

所以我们直接维护好那些要经过3边的点的个数,在每一次更改的时候在增增减减

直接上代码

AC_code
#include<bits/stdc++.h>
using namespace std;
#define re register int
#define pa pair<int,int>
#define mpa(x,y) make_pair(x,y)
#define gc if(++ip==ie)fread(ip=buf,1,SZ,stdin)
const int SZ=1<<19;
char buf[SZ],*ie=buf+SZ,*ip=ie-1;
inline int read(){
	int x;scanf("%d",&x);
	return x;
    /*gc;while(*ip<'-')gc;
    bool f=*ip=='-';if(f)gc;
    int x=*ip&15;gc;
    while(*ip>'-'){x*=10;x+=*ip&15;gc;}
    return f?-x:x;*/
}
const int N=3e5+5;
int n,m;
struct DJS{
	int fa[N],siz[N];
	DJS(){for(re i=1;i<=n;i++)fa[i]=i,siz[i]=1;}
	int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
	void add(int x,int y){
		int fx=find(x);
		int fy=find(y);
		if(fx!=fy){
			fa[fx]=fy;
			siz[fy]+=siz[fx];
		}
		return ;
	}
};
int to[N*2],nxt[N*2],val[N*2],head[N],rp;
void add_edg(int x,int y,int z){
	to[++rp]=y;
	val[rp]=z;
	nxt[rp]=head[x];
	head[x]=rp;
}
bool vis[N];
int fa[N],w[N];
void dfs(int x,int f,int v){
	w[x]=v;fa[x]=f;
	for(re i=head[x];i;i=nxt[i]){
		int y=to[i];
		if(y==f)continue;
		dfs(y,x,val[i]);
	}
}
int f[N];
signed main(){
	//scanf("%d%d",&n,&m);
	n=read();m=read();
	DJS a,b;
	for(re i=1,x,y,z;i<n;i++){
		//scanf("%d%d%d",&x,&y,&z);
		x=read();y=read();z=read();
		add_edg(x,y,z);add_edg(y,x,z);
	}
	//cout<<"finish edge"<<endl;
	dfs(1,0,0);
	//cout<<"finish dfs"<<endl;
	for(re i=1;i<=n;i++){
		//cout<<w[i]<<endl;
		if(w[i]==1)a.add(i,fa[i]);
		if(w[i]!=3)b.add(i,fa[i]);
	}
	for(re i=1;i<=n;i++){
		if(w[i]==3)f[a.find(fa[i])]+=b.siz[i];
	}
	//for(re i=1;i<=n;i++)cout<<f[i]<<endl;
	for(re i=1,x,y,s,t;i<=m;i++){
		//cout<<i<<endl;
		scanf("%d%d%d%d",&x,&y,&s,&t);
		if(fa[x]==y)swap(x,y);
		if(w[y]==3){
			f[a.find(x)]-=b.siz[y];
			f[a.find(fa[b.find(x)])]+=b.siz[y];
			b.add(y,x);
		}
		if(w[y]==2){
			f[a.find(x)]+=f[y];
			a.add(y,x);
		}
		if(w[y]!=1)w[y]--;
		int flag=0,ans=0;
		if(b.find(s)==b.find(t))flag=1;
		if(a.find(s)==a.find(fa[b.find(t)]))flag=1;
		if(b.find(fa[a.find(s)])==b.find(t))flag=1;
		if(flag)printf("1 ");
		else printf("0 ");
		ans=b.siz[b.find(s)]+f[a.find(s)];
		if(w[a.find(s)]==3)ans+=b.siz[b.find(fa[a.find(s)])];
		printf("%d\n",ans);
	}
}

标签:const,noip,int,ll,28,超能力,re,ret,define
来源: https://www.cnblogs.com/hzoi-fengwu/p/15090089.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有