多校冲刺 NOIP 20211104 模拟 (22)

T1 迷之阶乘

签到题,由于我实在垃圾,不会用\(pow\)这种高级东西,并且以为不让开\(int128\)于是傻不拉几的把边界的表给打了出来

二分,复杂度\(Tlog(n)^2\)

#include<bits/stdc++.h>
#define ull unsiged long long
#define int long long
using namespace std;
inline int read()
{
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	return x*f;
}
int n,l[21],rr[21];
struct node{int l,r;}p[21];
bool cmp(node a,node b){return a.l<b.l;}
inline int getnum(int x){int res=0;while(x){res++;x/=10;}return res;}
signed main()
{
	freopen("factorial.in","r",stdin);
	freopen("factorial.out","w",stdout);
	int t=read();
	rr[2]=1e9;rr[3]=1e6;rr[4]=40000;rr[5]=4000;
	rr[6]=1e3;rr[7]=430;rr[8]=200;rr[9]=100;rr[10]=65;rr[11]=40;
	rr[12]=29;rr[13]=20;rr[14]=13;rr[15]=10;rr[16]=6;rr[17]=4;
	rr[18]=2;rr[19]=1;
	while(t--)
	{
		n=read();
		for(int i=20;i>=1;i--) p[i].l=p[i].r=-1;
		if(n==1){puts("-1");continue;}
		p[1].l=n;p[1].r=n-1;
		for(int i=2;i<=19;i++)
		{
			int l=1,r=rr[i],mid;
			int ans=-1;
			while(l<=r)
			{
				mid=(l+r)>>1;int res=1; int num=0;
				for(int j=mid+1;j<=mid+i;j++) num+=getnum(j)-1;
				if(num>=18) {r=mid-1;continue;}
				for(int j=mid+1;j<=mid+i;j++) res=res*j;
				if(res>n) r=mid-1; else if(res<n) l=mid+1;
				else {ans=mid;break;}
			}
			if(ans!=-1) p[i].l=ans+i,p[i].r=ans;
		}			
		sort(p+1,p+1+19,cmp);int cnt=0;
		for(int i=1;i<=19;i++) if(p[i].l!=-1) cnt++;
		printf("%lld\n",cnt);
		for(int i=1;i<=19;i++) if(p[i].l!=-1) 
		printf("%lld %lld\n",p[i].l,p[i].r);
	}
}	

T2 子集

特判断\(k=1\)的情况,然后分奇偶处理

\(n/k\)\(m\)

\(m\)为偶数的话显然都有解,瞎算就行了

考虑为奇数的情况,\(m=1\)显然无解

\(k,m\)皆为奇数,可以先用前\(3k\)个数构成一个合法的方案,剩下的就是偶数的情况了

T3 混凝土粉末

比较弱,考场上值想到了主席树二分的\(qlog(n)^2\)的做法,结果跟\(qlog(n)^3\)\(q\sqrt{n}log(n)\)一个分

正解的话就是以时间为下标开一棵线段树,然后扫描线维护一下就行了

#include<bits/stdc++.h>
#define ull unsiged long long
#define ll long long
#define lid id<<1
#define rid id<<1|1
using namespace std;
inline ll read()
{
	ll x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	return x*f;
}
const int maxn=1e6+5;
ll sum[maxn*4];int n,m,ans[maxn];
struct node{int x,id;ll h;};bool vis[maxn];
vector<node>ins[maxn],que[maxn],del[maxn];
inline void update(int id,int l,int r,int pos,ll val)
{
	sum[id]+=val;if(l==r)return;
	int mid=(l+r)>>1;
	if(pos<=mid) update(lid,l,mid,pos,val);
	if(pos>mid) update(rid,mid+1,r,pos,val);
}
inline int query(int id,int l,int r,ll val)
{
	if(l==r) return l; int mid=(l+r)>>1;
	if(sum[lid]>=val) return query(lid,l,mid,val);
	else return query(rid,mid+1,r,val-sum[lid]);
}
signed main()
{
	freopen("concrete.in","r",stdin);
	freopen("concrete.out","w",stdout);
	n=read(); m=read();
	for(int i=1;i<=m;i++)
	{
		int type=read();
		if(type==1)
		{
			int l=read(),r=read(),h=read();
			ins[l].push_back((node){l,i,h});
			del[r].push_back((node){r,i,h});
		}
		else
		{
			int x=read();ll y=read();vis[i]=1;
			que[x].push_back((node){x,i,y});
		}
	}
	for(int i=1;i<=n;i++)
	{
		for(auto y:ins[i]) update(1,1,m,y.id,y.h);
		for(auto y:que[i])
		{
			if(sum[1]<y.h) continue;  
			int x=query(1,1,m,y.h);
			if(x<=y.id) ans[y.id]=x;
		}
		for(auto y:del[i]) update(1,1,m,y.id,-y.h);
	}
	for(int i=1;i<=m;i++) if(vis[i]) printf("%d\n",ans[i]);
}

T4 排水系统

先按照没有删除边跑以此,再根据期望的线性性再做一次,算出其他的部分

#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pii pair<int,int>
#define int long long
using namespace std;
inline int read()
{
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	return x*f;
}
const int maxn=5e5+5,mod=998244353;
int n,m,r,k,sum,inv,ans[maxn],h[maxn],w[maxn],du[maxn],normal[maxn],gai[maxn],cnt,chu[maxn],tmp[maxn],iv[maxn];
vector<pii>p[maxn];vector<int>pp[maxn];queue<int>q;
struct bb{int a,b,v;}edge[maxn];
inline int ksm(int x,int y){int res=1;x=x%mod;for(;y;y>>=1){if(y&1)res=res*x%mod;x=x*x%mod;}return res;}
bool bo[maxn];int pr[maxn];
inline void shai()
{
	iv[1]=1;for(int i=2;i<=n;i++)
	{if(!bo[i]){iv[i]=ksm(i,mod-2);pr[++cnt]=i;}for(int j=1;j<=cnt&&i*pr[j]<=n;j++)
	{bo[i*pr[j]]=1;iv[i*pr[j]]=iv[i]*iv[pr[j]]%mod;if(!(i%pr[j])) break;}}
}
signed main()
{
	freopen("water.in","r",stdin);
	freopen("water.out","w",stdout);
	n=read();m=read();r=read();k=read();
	for(int i=1;i<=m;++i)w[i]=1;shai();
	for(int i=1;i<=k;++i)
	{
		int a,b,v;
		scanf("%lld%lld%lld",&a,&b,&v);
		p[a].push_back(mp(b,v));
		++du[b]; sum+=v;
		edge[i]=(bb){a,b,v};
	}
	inv=ksm(sum,mod-2);
	for(int i=1;i<=m;++i)q.push(i),w[i]=1;
	memcpy(tmp,du,sizeof(tmp));
	while(!q.empty())
	{
		int x=q.front();q.pop(); if(!p[x].size())continue;
		int inv1=iv[p[x].size()],inv2=iv[p[x].size()-1];
		for(auto i:p[x])
		{	
			int v=i.fi,val=i.se;--du[v];
			chu[x]=(chu[x]+(w[x]*(inv2-inv1+mod)%mod)*val%mod*inv%mod*p[x].size()%mod)%mod;
			chu[v]=(chu[v]-w[x]*inv1%mod*val%mod*inv%mod-(w[x]*(inv2-inv1+mod)%mod)*val%mod*inv%mod+mod*2)%mod;
			w[v]=(w[v]+w[x]*inv1)%mod; if(!du[v])q.push(v);
		}
	}
	memcpy(du,tmp,sizeof(du));
	for(int i=1;i<=m;++i)chu[i]++;
	for(int i=1;i<=m;++i)q.push(i),w[i]=1;
	while(!q.empty())
	{
		int x=q.front();q.pop();
		int inv1=iv[p[x].size()];
		for(auto i:p[x])
		{
			int v=i.fi,val=i.se;--du[v];
			if(!du[v])q.push(v);
			chu[v]=(chu[v]+chu[x]*inv1)%mod;
		}
	}
	for(int i=n-r+1;i<=n;++i) printf("%lld ",chu[i]);
}

posted on 2021-11-04 17:03  JYFHYX  阅读(65)  评论(0编辑  收藏  举报