11.06 NOIP2024模拟赛#15 div1

小 L 说是信心赛

T1.现代量子力学在占卜中的应用

很高大上的题面

然鹅是二分+DP/贪心

可以套路的把 \(\geq mid\) 的设成 \(1\),否则为 \(-1\)\(\geq mid\) 的数为中位数时 \(\sum > 0\)

然后转换序列可以用 DP

二分中位数即可

Code
#include<bits/stdc++.h>
#define int long long
#define ll long long
#define fd(i,a,b) for(int i=(a),_i=(b);i<=_i;i=-~i)
#define bd(i,a,b) for(int i=(a);i>=(b);i=~-i)
#define endl '\n'
using namespace std;

//#define SIZE (1<<20)
//char In[SIZE],Out[SIZE],*p1=In,*p2=In,*p3=Out;
//#define getchar() (p1==p2&&(p2=(p1=In)+fread(In,1,SIZE,stdin),p1==p2)?EOF:*p1++)
inline int read()
{
	int x=0,f=1;char c=getchar();
	while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}
	while(c>='0'&&c<='9') {x=x*10+(c-48);c=getchar();}
	return x*f;
}

const int N=3e5+509,M=N,mod=998244353;

int n,a[N],b[N];

int f[N],g[N],dp[N];
int sumfl;
inline bool check(int x)
{
	//套路的把 >=mid 的设成 1,为中位数时 Σ=0
	fd(i,1,n) f[i]=(a[i]>=x?1:-1),g[i]=(b[i]>=x?1:-1);
	sumfl=0;fd(i,1,n) sumfl+=f[i];
	if(sumfl>0) return 1;
	int mx=-1e18;
	fd(i,1,n)
	{
		dp[i]=max(dp[i-1]+g[i]-f[i],g[i]-f[i]);
		mx=max(mx,dp[i]);
	}
	if(mx+sumfl>0) return 1;
	else return 0;
}

signed main()
{
#define FJ
#ifdef FJ
	freopen("quantum.in","r",stdin);
	freopen("quantum.out","w",stdout);
#else
//	#define Test
	#ifdef Test
	freopen("C:/Users/Lenovo/Desktop/比赛/2024.11.06/down/down/quantum1.in","r",stdin);
	freopen("C:/Users/Lenovo/Desktop/比赛/2024.11.06/down/down/quantum.out","w",stdout);
	#endif
#endif
//#define io
#ifdef io
	ios::sync_with_stdio(0);
	cin.tie(0);	cout.tie(0);
#endif
	
	n=read();
	fd(i,1,n) a[i]=read(),b[i]=read();
	
	int l=0,r=1e15,ans=0;
	
	while(l<=r)
	{
		int mid=((r-l)>>1)+l;
		if(check(mid)) ans=mid,l=mid+1;
		else r=mid-1;
	}
	
	printf("%lld",ans);
	
	return 0;
}

T2.憧憬成为电锯人

写的暴力,想到折半搜索了,但是没码

期望得分 \(71\),然鹅有一个点 T 了,然后一整个 \(\text{Subtask}\) 都没分

\(71 \rightarrow 65\)……

很多人剪枝冲过去了 \(71\)

Lydic 达捞用剪枝冲过去了 \(100\) 分,快来膜拜!

赛后有人剪枝冲过去了 \(100\)(水)

(看赛时别人的折半搜索怎么那么繁琐,不如我自己写……)

折半搜索代码
#include<bits/stdc++.h>
#define int long long
#define ll long long
#define fd(i,a,b) for(int i=(a),_i=(b);i<=_i;i=-~i)
#define bd(i,a,b) for(int i=(a);i>=(b);i=~-i)
#define endl '\n'
using namespace std;

//#define SIZE (1<<20)
//char In[SIZE],Out[SIZE],*p1=In,*p2=In,*p3=Out;
//#define getchar() (p1==p2&&(p2=(p1=In)+fread(In,1,SIZE,stdin),p1==p2)?EOF:*p1++)
inline int read()
{
	int x=0,f=1;char c=getchar();
	while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}
	while(c>='0'&&c<='9') {x=x*10+(c-48);c=getchar();}
	return x*f;
}

const int N=16,M=19,mod=998244353;

int h,w,s;
int a[N][N];

namespace SubI
{
	unordered_map<int,int> vis;
	
	inline void Print(int mskh,int mskw)
	{
		vector< pair<int,int> > ans;
		fd(i,1,h) if((mskh>>(i-1))&1) ans.push_back({1,i});
		fd(i,1,w) if((mskw>>(i-1))&1) ans.push_back({2,i});
		printf("YES\n%lld\n",(int)ans.size());
		for(auto &i:ans) printf("%lld %lld\n",i.first,i.second);
		exit(0);
	}
	
	int val[N];
	void solve(int mskh)
	{
		vis.clear();
		fd(i,1,w) val[i]=0;
		fd(i,1,h)
		{
			if((mskh>>(i-1))&1) continue;
			fd(j,1,w) val[j]+=a[i][j];
		}
		int mxw1=(1<<(w>>1))-1,mxw2=(1<<(w-(w>>1)))-1;
		fd(i,0,mxw1)
		{
			int mskw=i,Sum=0;
			fd(i,1,(w>>1)) if(!(mskw>>(i-1)&1)) Sum+=val[i];
			vis[Sum]=i;
		}
		fd(i,0,mxw2)
		{
			int mskw=i<<(w>>1),Sum=0;
			fd(i,(w>>1)+1,w) if(!(mskw>>(i-1)&1)) Sum+=val[i];
			if(vis.count(s-Sum)) Print(mskh,vis[s-Sum]+mskw);
		}
	}
	
	inline void Main()
	{
		int mxh=(1<<h)-1;
		fd(mskh,0,mxh) solve(mskh);
		puts("NO");
	}
}

signed main()
{
#define FJ
#ifdef FJ
	freopen("chainsaw.in","r",stdin);
	freopen("chainsaw.out","w",stdout);
#else
//	#define Test
	#ifdef Test
	freopen("C:/Users/Lenovo/Desktop/比赛/2024.11.06/down/down/chainsaw2.in","r",stdin);
	freopen("C:/Users/Lenovo/Desktop/比赛/2024.11.06/down/down/chainsaw.out","w",stdout);
	#endif
#endif
//#define io
#ifdef io
	ios::sync_with_stdio(0);
	cin.tie(0);	cout.tie(0);
#endif
	
	h=read(),w=read();
	fd(i,1,h) fd(j,1,w)
		a[i][j]=read();
	s=read();
	
	SubI::Main();
	
	return 0;
}

T3.超超超超喜欢你的一百个数据结构题

写的暴力,然后发现过不去大样例

然后神奇判断一下过了第一个大样例

但是 WA 了(不是你大样例 \(3000\) 多组都没 WA)

正解很神奇:

还要卡常,差评

Code
#include<bits/stdc++.h>
#define ll long long
#define fd(i,a,b) for(int i=(a),_i=(b);i<=_i;i=-~i)
#define bd(i,a,b) for(int i=(a);i>=(b);i=~-i)
#define endl '\n'
using namespace std;

struct IO
{
	static const int S=1<<21;
	char buf[S],*p1,*p2;int st[105],Top;
	~IO(){clear();}
	inline void clear(){fwrite(buf,1,Top,stdout);Top=0;}
	inline void pc(const char c){Top==S&&(clear(),0);buf[Top++]=c;}
	inline char gc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
	inline IO&operator >> (char&x){while(x=gc(),x==' '||x=='\n'||x=='\r');return *this;}
	template<typename T>inline IO&operator >> (T&x)
	{
		x=0;bool f=0;char ch=gc();
		while(!isdigit(ch)){if(ch=='-') f^=1;ch=gc();}
		while(isdigit(ch)) x=(x<<3)+(x<<1)+ch-'0',ch=gc();
		f?x=-x:0;return *this;
	}
	inline IO&operator << (const char c){pc(c);return *this;}
	template<typename T>inline IO&operator << (T x)
	{
		if(x<0) pc('-'),x=-x;
		do{st[++st[0]]=x%10,x/=10;}while(x);
		while(st[0]) pc('0'+st[st[0]--]);return *this;
	}
}io;
#define cin io
#define cout io

const int N=8e5+509,M=1e6+509,mod=998244353;

struct DSU
{
	int fa[N];
	int get(int x)
	{
		if(x==fa[x]) return x;
		else return fa[x]=get(fa[x]);
	}
	inline void add(int x,int y)
	{
		x=get(x),y=get(y);
		if(x!=y) fa[x]=y;
	}
};
struct Edge{int y,nxt;};
struct Line{int x,y;};

int n,m,q;
int head[N],tot=1;
int op[M],u[M],v[M];
Edge E[M<<1];
Line e[M];
DSU bin,kk;
inline void add(int x,int y)
{
	E[++tot]={y,head[x]},head[x]=tot;
}

int dfn[N],low[N],tim;
bitset<M> is,no,ans;
bitset<N> vis;
bitset<M<<1> br;

void tarjan(int x,int ine)
{
	dfn[x]=low[x]=++tim;
	for(int i=head[x];i;i=E[i].nxt)
	{
		int y=E[i].y;
		if(!dfn[y])
		{
			tarjan(y,i);
			low[x]=min(low[x],low[y]);
			if(low[y]>dfn[x]) br[i]=br[i^1]=1;//桥
		}
		else if(i!=(ine^1)) low[x]=min(low[x],dfn[y]);
	}
}

int bel[N],cnt,id[N];
vector<int> g[N];

void dfs(int x)
{
	bel[x]=id[x]=cnt;
	for(int i=head[x];i;i=E[i].nxt)
	{
		int y=E[i].y;
		if(br[i])
		{
			if(bel[y])
			{
				g[bel[x]].push_back(bel[y]);
				g[bel[y]].push_back(bel[x]);
			}
		}
		else if(!bel[y]) dfs(y);
	}
}

int len,dep[N],fa[N];

void dfss(int x,int fat)
{
	vis[x]=1;
	dep[x]=dep[fat]+1,fa[x]=fat;
	kk.fa[x]=x;
	for(int &y:g[x])
	{
		if(y==fat) continue;
		dfss(y,x);
	}
}

inline void printS(int flag)
{
	if(flag) cout.pc('Y'),cout.pc('E'),cout.pc('S'),cout.pc('\n');
	else cout.pc('N'),cout.pc('O'),cout.pc('\n');
}

signed main()
{
#define FJ
#ifdef FJ
	freopen("datastructure.in","r",stdin);
	freopen("datastructure.out","w",stdout);
#else
//	#define Test
	#ifdef Test
	freopen("C:/Users/Lenovo/Desktop/比赛/2024.11.06/down/down/datastructure1.in","r",stdin);
	freopen("C:/Users/Lenovo/Desktop/比赛/2024.11.06/down/down/datastructure.out","w",stdout);
	#endif
#endif
//#define io
#ifdef io
	ios::sync_with_stdio(0);
	cin.tie(0);	cout.tie(0);
#endif
	
	cin>>n>>m>>q;
	int Id;cin>>Id;
	
	fd(i,1,m) cin>>e[i].x>>e[i].y;
	
	fd(i,1,q)
	{
		cin>>op[i]>>u[i];
		if(op[i]==2) cin>>v[i];
		else is[u[i]]=1;
	}
	
	fd(i,1,n) bin.fa[i]=i;
	fd(i,1,m)
	{
		if(!is[i])
		{
			add(e[i].x,e[i].y);
			add(e[i].y,e[i].x);
			bin.add(e[i].x,e[i].y);
		}
	}
	
	bd(i,q,1)
	{
		if(op[i]==1)
		{
			int fx=bin.get(e[u[i]].x),fy=bin.get(e[u[i]].y);
			if(fx!=fy)
			{
				no[u[i]]=1;
				add(e[u[i]].x,e[u[i]].y);
				add(e[u[i]].y,e[u[i]].x);
				bin.add(fx,fy);
			}
		}
	}
	
	fd(i,1,n) if(!dfn[i]) tarjan(i,0);
	fd(i,1,n) if(!bel[i]) cnt++,dfs(i);
	fd(i,1,n) if(!vis[i]) dfss(i,0);
	
	bd(i,q,1)
	{
		if(op[i]==1)
		{
			if(no[u[i]]) continue;
			int x=id[e[u[i]].x],y=id[e[u[i]].y];
			if(kk.get(x)==kk.get(y)) continue;
			while(x!=y)
			{
				if(dep[x]>dep[y]) kk.add(x,fa[x]),x=kk.get(fa[x]);
				else kk.add(y,fa[y]),y=kk.get(fa[y]);
			}
		}
		else ans[++len]=(kk.get(id[u[i]])==kk.get(id[v[i]]));
	}
	
	bd(i,len,1)
	{
		printS(ans[i]);
	}
	
	return 0;
}

T4.为美好的世界染上色彩

没看

但是 \(50\) 分应该可以拿……

总结

  • T2 想到折半搜索了,但是……
  • T3 的暴力分挂力
  • 赛时特别困
posted @ 2024-11-06 16:49  whrwlx  阅读(14)  评论(0编辑  收藏  举报