Loading

noip模拟25

A.random

数学推理.

A_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS
{
	#define ll long long int
	#define re register ll 
	#define lf double
	#define lb lower_bound 
	#define ub upper_bound 
	#define mp make_pair
	#define File(x,y) freopen(#x,"r",stdin),freopen(#y,"w",stdout)
	#define Fill(x,y) memset(x,y,sizeof x);
	#define Copy(x,y) memset(y,x,sizeof x);
	inline ll read()
	{
		ll ss=0; bool cit=1; char ch;
		while(!isdigit(ch=getchar())) if(ch=='-') cit=0;
		while(isdigit(ch)) ss=(ss<<3)+(ss<<1)+(ch^48),ch=getchar();
		return cit?ss:-ss;
	}
	inline void write(ll ss)
	{
		static int stas[35]; int topps=0;
  		if(ss<0) putchar('-'),ss=-ss;
  		do{stas[++topps]=ss%10,ss/=10;}while(ss);
  		while(topps) putchar(stas[topps--]+48); puts("");
	}
} using namespace BSS;

const ll mod=998244353;

ll m,n,ts;
inline ll ksm(ll a,ll b,ll c)
{
	a%=c; ll temp=1;
	while(b)
	{
		if(b&1) temp=(temp*a)%c;
		b>>=1; a=(a*a)%c;
	}
	return temp%c;
}
signed main()
{
	ts=read(); ll tmp=ksm(9,mod-2,mod);
	while(ts--)
	{
		n=read();
		ll temp=n%mod; temp=(temp*temp)%mod;
		temp=(temp+mod-1)%mod;
		temp=(temp*tmp)%mod;
		write(temp);
	}
	return 0;
}

B.string

选择将所有模式串正着和倒着插入两棵Trie树..
我们发现如果一段字符串可以匹配文本串,那么这个字符串的任意一段前缀/后缀都可以进行匹配..
所以我们可以维护Trie树上的方案前缀和..
于是可以枚举断点,二分可以匹配的最长后缀/前缀,统计答案即可..

B_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS
{
	#define ll unsigned long long int
	#define re register long long int
	#define lf double
	#define lb lower_bound 
	#define ub upper_bound 
	#define mp make_pair
	#define File(x,y) freopen(#x,"r",stdin),freopen(#y,"w",stdout)
	#define Fill(x,y) memset(x,y,sizeof x);
	#define Copy(x,y) memset(y,x,sizeof x);
	inline ll read()
	{
		ll ss=0; bool cit=1; char ch;
		while(!isdigit(ch=getchar())) if(ch=='-') cit=0;
		while(isdigit(ch)) ss=(ss<<3)+(ss<<1)+(ch^48),ch=getchar();
		return ss;
	}
} using namespace BSS;

const ll N=5e5+50;
const ll p=131;

ll m,n,ls,tsp,tss;
char s[N],s2[N*2];
ll trp[N*2][27],trs[N*2][27];
ll pre[N*60],suf[N*60],spre[N*2],ssuf[N*2];
ll down[N+50];
unordered_map<ll,ll> mp1,mp2;
void insert_pre()
{	
	ll p=0; ll len=strlen(s2+1);
	for(ll i=1;i<=len;i++)
	{
		if(!trp[p][s2[i]-'a'+1])
			trp[p][s2[i]-'a'+1]=++tsp;
		p=trp[p][s2[i]-'a'+1];			
		pre[p]++;
	}
	return ;
}
void insert_suf()
{
	ll p=0; ll len=strlen(s2+1);
	for(ll i=1;i<=len;i++)
	{
		if(!trs[p][s2[i]-'a'+1])
			trs[p][s2[i]-'a'+1]=++tss;
		p=trs[p][s2[i]-'a'+1];
		suf[p]++;
	}
	return ;
}
void dfs_pre(ll now,ll hash,ll val)
{
//	printf("Pre:%llu %llu\n",hash,val);
	mp1[hash]=val;
	for(ll i=1;i<=26;i++)
	{
		if(trp[now][i])
		{
			dfs_pre(trp[now][i],hash*p+i,val+pre[trp[now][i]]);
		}
	}
	return ;
}
void dfs_suf(ll now,ll hash,ll val)
{
//	printf("Suf:%llu %llu\n",hash,val);
	mp2[hash]=val;
	for(ll i=1;i<=26;i++)
	{
		if(trs[now][i])
		{
			dfs_suf(trs[now][i],hash*p+i,val+suf[trs[now][i]]);
		}
	}
	return ;
}
inline ll check_front(ll now)
{
	ll l=1,r=now,mid; ll temp;
	while(l<=r)
	{
		mid=(l+r)>>1;
		temp=ssuf[mid]-ssuf[now+1]*down[now-mid+1];
		if(mp2.find(temp)!=mp2.end()) r=mid-1;
		else l=mid+1;
	}
	temp=ssuf[l]-ssuf[now+1]*down[now-l+1];
	return mp2[temp];
}
inline ll check_back(ll now)
{
	ll l=now,r=ls,mid; ll temp;
//	cout<<"now:"<<now<<endl;
	while(l<=r)
	{
		mid=(l+r)>>1;
//		cout<<"L:"<<l<<" R:"<<r<<" Mid:"<<mid<<" ";
		temp=spre[mid]-spre[now-1]*down[mid-now+1];
//		cout<<"temp:"<<temp<<endl;
//		for(re i=now;i<=mid;i++) cout<<s[i]<<" ";
//		cout<<endl;
		if(mp1.find(temp)!=mp1.end()) l=mid+1;
		else r=mid-1;
	}
//	cout<<"l:"<<l<<" r:"<<r<<" mid:"<<mid<<endl;
	temp=spre[r]-spre[now-1]*down[r-now+1];
	return mp1[temp];
}
signed main()
{
	scanf("%s",s+1);
	ls=strlen(s+1);
	n=read();
	for(ll i=1;i<=n;i++)
	{
		scanf("%s",s2+1);
		insert_pre();
		reverse(s2+1,s2+1+strlen(s2+1));
		insert_suf();
	}
	for(ll i=1;i<=26;i++)
	{
		if(trp[0][i]) dfs_pre(trp[0][i],i,pre[trp[0][i]]);
		if(trs[0][i]) dfs_suf(trs[0][i],i,suf[trs[0][i]]);
	}
	down[0]=1;
	for(ll i=1;i<=N-50;i++)
		down[i]=down[i-1]*p;
	for(ll i=1;i<=ls;i++)
		spre[i]=spre[i-1]*p+s[i]-'a'+1;
	for(ll i=ls;i>=1;i--)
		ssuf[i]=ssuf[i+1]*p+s[i]-'a'+1;
	ll temp1,temp2,ans=0;
	for(ll i=1;i<=ls-1;i++)
	{
		temp1=check_front(i);
		temp2=check_back(i+1);
		ans+=temp1*temp2;
	}
	printf("%lld",ans);
	return 0;
}

C.queen

考场上想着要什么正难取反,但这其实是一个极其分类讨论的题目..
大家都写的是直接写式子,而我选择了数形结合使用组合数目..
统计不同情况的前缀和,发现是等差数列,于是选择使用组合数..
首先画出矩阵,然后填数+切割,计算前缀即可,组合数优化..

C_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS
{
	#define ll long long int
	#define re register ll 
	#define lf double
	#define lb lower_bound 
	#define ub upper_bound 
	#define mp make_pair
	#define File(x,y) freopen(#x,"r",stdin),freopen(#y,"w",stdout)
	#define Fill(x,y) memset(x,y,sizeof x);
	#define Copy(x,y) memset(y,x,sizeof x);
	inline ll read()
	{
		ll ss=0; bool cit=1; char ch;
		while(!isdigit(ch=getchar())) if(ch=='-') cit=0;
		while(isdigit(ch)) ss=(ss<<3)+(ss<<1)+(ch^48),ch=getchar();
		return cit?ss:-ss;
	}
	inline void write(ll ss)
	{
		static int stas[35]; int topps=0;
  		if(ss<0) putchar('-'),ss=-ss;
  		do{stas[++topps]=ss%10,ss/=10;}while(ss);
  		while(topps) putchar(stas[topps--]+48); puts("");
	}
} using namespace BSS;

const ll mod=3e5+7;

ll m,n,num,ts;
ll ny[mod+50],add[mod+50];
inline ll ksm(ll a,ll b,ll c)
{
	a%=c; ll temp=1;
	while(b)
	{
		if(b&1) temp=(temp*a)%c;
		b>>=1; a=(a*a)%c;
	}
	return temp%c;
}
inline ll C(ll a,ll b)
{
	if(a>b) return 0;
	return ((add[b]*ny[a]%mod)*ny[b-a])%mod;
}
ll lucas(ll a,ll b)
{
	if(a==0) return 1;
	if(b==0 or a==b) return 1;
	return (C(a%mod,b%mod)*lucas(a/mod,b/mod))%mod;
}
void Prepare()
{
	add[0]=1;
	for(re i=1;i<=mod;i++) 
		add[i]=(add[i-1]*i)%mod,ny[i]=ksm(add[i],mod-2,mod);
	return ;
}
ll Work_Line(ll n,ll m,ll num)
{
	if(num>n and num>m) return 0;
	if(n<m) swap(n,m);
	ll temp=(lucas(num,n)*(m%mod))%mod;
	if(num>m) return temp;
	ll ans=(lucas(num,m)*(n%mod))%mod;
	ans=(ans+temp)%mod;
	temp=(lucas(num+1,m)*2)%mod;
	temp=(temp+(((n-m+1)%mod)*lucas(num,m))%mod)%mod;
	temp=(temp*2)%mod;
	ans=(ans+temp)%mod;
	return ans;
}
ll Work_Square(ll n,ll m)
{
	ll ans=(lucas(3,m+1)+lucas(3,m))%mod;
	ll temp=(n-m)%mod; temp=(temp*lucas(2,m))%mod;
	ans=(ans+temp)%mod; ans=ans%mod;
	return ans;
}
ll Work_Square23(ll n,ll m)
{
	if(n<3) return 0;
	if(m<2) return 0;
	ll ans=0,temp;
	if(n>=2*m)
	{
		temp=(n-2*m)%mod; temp=(temp*lucas(2,m))%mod;
		temp=(temp+(lucas(3,m)*2))%mod;
		temp=(temp+(lucas(3,m+1)*2)%mod)%mod;
		ans=(ans+temp)%mod;
	}
	else
	{
		ll t=n>>1;
		if(n&1)
		{
			temp=(m-t)%mod; temp=(temp*(t%mod))%mod;
			temp=(temp+lucas(2,t))%mod;
			ll tmp=(m-t)%mod; tmp=(tmp<<1)%mod;
			tmp=(tmp*lucas(2,t))%mod;
			temp=(temp+tmp)%mod;
			temp=(temp+(lucas(3,t)*2)%mod)%mod;
			temp=(temp+(lucas(3,t+1)*2)%mod)%mod;
			ans=(ans+temp)%mod;
		}
		else
		{
			temp=(m-t)%mod; temp=(temp*lucas(2,t))%mod;
			temp=(temp+lucas(3,t))%mod; temp=(temp+lucas(3,t+1))%mod;
			temp=(temp<<1)%mod; 
			ans=(ans+temp)%mod;
		}
	}
	return (ans*2)%mod;
}
ll Work_Odd(ll n,ll m)
{
	if(m==1) return 0;
	ll t=(m>>1),ans=0;
	if(m&1)
	{
		ans=((lucas(3,t+1)%mod)<<3)%mod;
		ll temp=(n-m+1)%mod;
		temp=(temp*((lucas(2,t)+lucas(2,t+1)%mod)))%mod;
		ans=(ans+temp)%mod;
		ans=(ans-(lucas(2,t)*2%mod)+mod*mod)%mod;
	}
	else
	{
		ans=(lucas(3,t+1)+lucas(3,t))%mod;
		ans=(ans<<2)%mod;
		ll temp=(lucas(2,t)*2)%mod;
		temp=(((n-m)%mod)*temp)%mod;
		ans=(ans+temp)%mod;
	}
	return ans;
}
signed main()
{
	Prepare();
	ts=read();
	ll m,n,num;
	while(ts--)
	{
		n=read(); m=read(); num=read();
		if(n<m) swap(n,m); // 使得 n > m
		if(num==1)
		{
			write(((n%mod)*(m%mod))%mod);
			continue;
		}
		if(num==2 or num>5) 
		{
			ll ans=Work_Line(n,m,num);
			write(ans);
			continue;
		}
		if(num==3)
		{
			ll ans=(Work_Square(n,m)<<2)%mod;
			ans=(ans+Work_Square23(n,m))%mod;
			ans=(ans+Work_Square23(m,n))%mod;
			ans=(ans+Work_Line(n,m,num))%mod;
			write(ans);
			continue;
		}
		if(num==4)
		{
			ll ans=(Work_Odd(n,m)*5)%mod;
			ans=(ans+Work_Square(n,m))%mod;
			ans=(ans+Work_Square23(m,n))%mod;
			ans=(ans+Work_Square23(n,m))%mod;
			ans=(ans+Work_Line(n,m,num))%mod;
			write(ans); 
			continue;			
		}
		if(num==5)
		{
			ll ans=(Work_Odd(n,m)*2)%mod;
			ans=(ans+Work_Line(n,m,num))%mod;
			write(ans); 
			continue;	
		}
	}	
}
posted @ 2021-08-05 20:04  AaMuXiiiiii  阅读(29)  评论(0编辑  收藏  举报