码迷,mamicode.com
首页 > 其他好文 > 详细

联赛测试 3.22

时间:2021-04-02 13:15:06      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:地方   const   end   没有   out   dig   struct   选择   get   

A. x

很容易可以想到分解质因数,使用并查集把相同因子的放一块儿,计算出最终有 \(cnt\) 个块,答案为 \(2^{cnt}-2\) (可以理解为为每个块都有左集合与右集合两个选择,而最终出现2个空集的情形,需要从答案中减去)

然鹅,事情并没有这么简单~

因为 \(a_i\) 上界为 \(10^6\) ,常规的分解为n根号级别会被卡,于是需要先分解质因数再枚举是否整除

B. y

一看数据范围异常地小,可以想到状压。设计状态 \(f[i][j]\) 表示边的状态为\(i\) 且最后一个点为 \(j\) 是否可行。当以u为结尾的某个状态可行时,枚举所有相连的点,更新状态。

然鹅,事情并没有这么简单~

这样的时间复杂度为 \(O(2^d* n^2)\),最大数据过不去。最神奇的地方在于这题由于路径具有可拼接性,于是用折半搜索的思想,从前从后各计算一半再拼起来

#include<bits/stdc++.h>
using namespace std;
const int maxn=(1<<21)+5;
const int maxm=100005;
int n,m,d,hd[maxm],cnt,ans,x,y,w;
bool f[maxn][105][2];
int read(){
	int x=0,f=1;
	char ch=getchar();
	while(!isdigit(ch)){
		if(ch==‘-‘)f=-1;
		ch=getchar();
	}
	while(isdigit(ch)){
		x=x*10+ch-48;
		ch=getchar();
	}
	return x*f;
}
struct Edge{
	int nxt,to,val;
}edge[maxm];
void add(int u,int v,int w){
	edge[++cnt].nxt=hd[u];
	edge[cnt].to=v;
	edge[cnt].val=w;
	hd[u]=cnt;
	return ;
}
int main(){
//	freopen("shuju.in","r",stdin);
//	freopen("my.out","w",stdout);
	n=read();
	m=read();
	d=read();
	for(int i=1;i<=m;i++){
		x=read();
		y=read();
		w=read();
		add(x,y,w);
		add(y,x,w);
		if(x==1)f[2+w][y][0]=true;
		if(y==1)f[2+w][x][0]=true;
		f[2+w][x][1]=true;
		f[2+w][y][1]=true;
	}
	for(int i=1;i<d/2;i++){
		for(int j=(1<<i);j<=2*(1<<i)-1;j++){
			for(int u=1;u<=n;u++){
				if(f[j][u][0]){
					for(int k=hd[u];k;k=edge[k].nxt){
						int v=edge[k].to;
						f[(j<<1)+edge[k].val][v][0]=true;
					}
				}
			}
		}
	}
	for(int i=1;i<=d-d/2;i++){
		for(int j=(1<<i);j<=2*(1<<i)-1;j++){
			for(int u=1;u<=n;u++){
				if(f[j][u][1]){
					for(int k=hd[u];k;k=edge[k].nxt){
						int v=edge[k].to;
						f[(j<<1)+edge[k].val][v][1]=true;
					}
				}
			}
		}
	}
	for(int i=0;i<=(1<<d)-1;i++){
		for(int j=1;j<=n;j++){
//			cout<<i<<" "<<(1<<(d/2))+(i>>(d-d/2))<<" "<<(1<<(d-d/2))+(i&((1<<(d-d/2))-1))<<endl;
			if(f[(1<<(d/2))+(i>>(d-d/2))][j][0]==true&&f[(1<<(d-d/2))+(i&((1<<(d-d/2))-1))][j][1]){
//				cout<<i<<endl;
				ans++;
				break;
			}
		}
	}
	cout<<ans;
	return 0;
}

C. z

emmm……总之,这道题比较毒瘤~

联赛测试 3.22

标签:地方   const   end   没有   out   dig   struct   选择   get   

原文地址:https://www.cnblogs.com/yang-cx/p/14607995.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!