noip模拟12

T1

和昨天一样,处理出一个大小较小的区间的问题,logn求答案。对于重复的\(i\)特判求解即可。

Code

#include<cstring>
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<vector>
namespace EMT{
	#define pf printf
	#define F(i,a,b) for(register int i=a;i<=b;i++)
	#define D(i,a,b) for(register int i=a;i>=b;i--)
	typedef long long ll;
	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*10+ch-'0',ch=getchar();return x*f;}
	inline int min(int a,int b){return a<b?a:b;}inline int max(int a,int b){return a>b?a:b;}
	inline void pi(ll x){pf("%lld ",x);}inline void pn(){pf("\n");}
	inline void file(){freopen("in.in","r",stdin);freopen("my.out","w",stdout);}
	const int N=3e5+100,M=1e6+100;std::vector<int>v[M];
	int a[N],n,mod;
	struct dd{int od,v;}st[N],pp;int l[N],r[N],top,ans,pre[N];
	inline int get(int x,int y){return x+y>=mod?x+y-mod:x+y;}
	inline int teg(int x,int y){return x>y?x-y:(x==y?0:x-y+mod);}
	inline void solve(int k,int L,int R,bool opt){
		//pi(k);pi(L);pi(R);pi(opt);pn();
		if(opt){
			F(i,L,R){
				int t=get(pre[i-1],a[k]);//pi(t);pn();
				int x=lower_bound(v[t].begin(),v[t].end(),k)-v[t].begin();
				int y=upper_bound(v[t].begin(),v[t].end(),r[k])-v[t].begin();
				//pi(x),pi(y);pn();
				ans+=y-x;
			}if(get(pre[k-1],a[k])==pre[k])--ans;
		}else{
			F(i,L,R){
				int t=teg(pre[i],a[k]);//pi(t);pn();
				int x=lower_bound(v[t].begin(),v[t].end(),l[k]-1)-v[t].begin();
				int y=upper_bound(v[t].begin(),v[t].end(),k-1)-v[t].begin();
				//pi(x),pi(y);pn();
				ans+=y-x;
			}if(teg(pre[k],a[k])==pre[k-1])--ans;
		}
	}
	inline short main(){
		//file();
		n=read();mod=read();
		F(i,1,n){a[i]=read();pre[i]=(pre[i-1]+a[i])%mod;}
		F(i,1,n){
			pp.v=a[i],pp.od=i;l[i]=r[i]=i;
			while(top&&st[top].v<a[i])r[st[top].od]=i-1,l[i]=l[st[top].od],top--;
			st[++top]=pp;
		}while(top)r[st[top].od]=n,top--;F(i,1,n)a[i]%=mod;
		v[0].push_back(0);
		F(i,1,n)v[pre[i]].push_back(i);//,pi(pre[i]);pn();
		F(i,1,n){
			if(l[i]!=r[i]){
				if(i-l[i]<=r[i]-i)solve(i,l[i],i,1);
				else solve(i,i,r[i],0);
			}
		}
		pi(ans);
		return 0;
	}
}
signed main(){return EMT::main();}

T2

当m<mod时,暴力分子分母取膜,分母减分子求答案。
否则,分子是0,用蓝书上说的\(n!\)\(P\)的个数为

\(\sum_{i=1}^{i<=log_p^n}n/p^i\)(向下取整)

于是约分求逆元即可。

Code



#include<cstring>
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
namespace EMT{
	#define pf printf
	#define F(i,a,b) for(register int i=a;i<=b;i++)
	#define D(i,a,b) for(register long long i=a;i>=b;i--)
	typedef long long ll;
	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*10+ch-'0',ch=getchar();return x*f;}
	inline int min(int a,int b){return a<b?a:b;}inline int max(int a,int b){return a>b?a:b;}
	inline void pi(int x){pf("%d ",x);}inline void pn(){pf("\n");}
	inline void file(){freopen("in.in","r",stdin);freopen("my.out","w",stdout);}
	ll n,m,bin[65],cnt,B=1;const int mod=1e6+3;
	inline ll ksm(ll a,ll b){
		ll ans=1;
		while(b){
			if(b&1)ans=ans*a%mod;
			b>>=1;
			a=a*a%mod;
		}return ans;
	}
	inline int fen(ll x){
		int cnt=0;
		B=B*(ksm(2,n)-x+mod)%mod;
		while(!(x%2))x/=2,++cnt;
		return cnt;
	}
	inline short main(){
		n=read(),m=read();bin[0]=1;
		F(i,1,63)bin[i]=bin[i-1]<<1;
		if(m>mod){
			ll cnt=0;
			F(i,1,63)if(m-1>=bin[i])cnt+=(m-1)/bin[i];else break;
			ll ans=ksm(2,n);ans=ksm(ans,m-1);
			ll inv=ksm(2,cnt);inv=ksm(inv,mod-2);
			ans=ans*inv%mod;
			pi(ans);pi(ans);return 0;
		}
		ll ans=ksm(2,n);ans=ksm(ans,m-1);
		ll inv=0;F(i,1,m-1)inv+=fen(i);
		inv=ksm(2,inv);inv=ksm(inv,mod-2);
		ans=ans*inv%mod;B=B*inv%mod;
		pi((ans-B+mod)%mod);pi(ans);
		return 0;
	}
}
signed main(){return EMT::main();}

T3

调了一下午,不亏!

up数组用来求最大值,down数组用来挡刀,只管up大,down合法即可。

求得最大值后直接dfs求方案,不知道为什么不会T,欢迎来hack~

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#define pf printf
#define F(i,a,b) for(register int i=a;i<=b;i++)
#define D(i,a,b) for(register int i=a;i>=b;i--)
typedef long long ll;
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*10+ch-'0',ch=getchar();return x*f;}
inline int min(int a,int b){return a<b?a:b;}inline int max(int a,int b){return a>b?a:b;}
inline void pi(int x){pf("%d ",x);}inline void pn(){pf("\n");}
inline void file(){freopen("in.in","r",stdin);freopen("my.out","w",stdout);}
const int N=2e5+100;int a[N],s[N],n,rec[N],cnt;
struct node{int val,len;}up[N],down[N];
inline void dfs(int k){
	//pf("k : %d  k+1 : %d  a[k+1] : %d  s[a[k+1]] : %d  rec[k+1] : %d\n",k,k+1,a[k+1],s[a[k+1]],rec[k+1]);
	if(a[k+1]<1||s[a[k+1]]>5)return;
	if(k<=0){if(a[2]!=1)return;F(i,1,n)pi(rec[i]);exit(0);}
	if(a[k]){if(a[k]!=a[k+1]-1&&a[k]!=a[k+1])return;if(s[a[k+1]]==1&&a[k+1]!=a[k])return;s[a[k]]++;if(s[a[k]]>5){s[a[k]]--;return;}rec[k]=a[k],dfs(k-1);s[a[k]]--;}
	else{
		if(s[a[k+1]]==1)a[k]=a[k+1],s[a[k]]++,rec[k]=a[k],dfs(k-1),s[a[k]]--,a[k]=0;
		else if(s[a[k+1]]==5)a[k]=a[k+1]-1,s[a[k]]++,rec[k]=a[k],dfs(k-1),s[a[k]]--,a[k]=0;
		else{
			a[k]=a[k+1];    s[a[k]]++,rec[k]=a[k],dfs(k-1);s[a[k]]--;
			a[k]=a[k+1]-1;s[a[k]]++;rec[k]=a[k];dfs(k-1);s[a[k]]--;a[k]=0;
		}
	}
}
int main(){
	file();
	n=read();F(i,1,n)a[i]=read();a[1]=1;
	up[1].val=up[1].len=down[1].val=down[1].len=1;
	F(i,1,n-1)if(a[i]&&a[i+1]&&a[i+1]<a[i]){pi(-1);return 0;}
	if(a[n]&&a[n-1]&&a[n-1]!=a[n]){pi(-1);return 0;}
	F(i,2,n){
		if(a[i]){
			if(up[i-1].val<a[i]&&up[i-1].len<2){pi(-1);return 0;}
			if(down[i-1].val>a[i]){pi(-1);return 0;}
			if(down[i-1].val==a[i]&&down[i-1].len==5){pi(-1);return 0;}
			if(up[i-1].val<a[i]-1){pi(-1);return 0;}
			if(up[i-1].val<a[i]||up[i-1].val>a[i])up[i].val=a[i],up[i].len=(a[i-1]?1:2);
			if(up[i-1].val==a[i])up[i].val=a[i],up[i].len=up[i-1].len+1;
			if(down[i-1].val==a[i])down[i].val=down[i-1].val,down[i].len=down[i-1].len+1;
			if(down[i-1].val<a[i])down[i].val=a[i],down[i].len=1;
		}
		else{
			if(up[i-1].len==1)up[i].val=up[i-1].val,up[i].len=2;
			else up[i].val=up[i-1].val+1,up[i].len=1;
			if(down[i-1].len==5)down[i].val=down[i-1].val+1,down[i].len=1;
			else down[i].val=down[i-1].val,down[i].len=down[i-1].len+1;
		}
	}
	pi(up[n].len>=2?up[n].val:up[n].val-1);pn();a[n]=rec[n]=up[n].len>=2?up[n].val:up[n].val-1;s[a[n]]=1;
	dfs(n-1);
	return 0;
}

posted @ 2021-07-12 20:28  letitdown  阅读(33)  评论(0编辑  收藏  举报