8.4

赛事发现只和 sqrt 下还是整数的部分有关系,然后先把 \(m\) 换了。
接着实际一个 \(O(nm)\) 的暴力,发现答案是 \(C ^{n-1}_{m+n-1}\) 写完了。
为什么呢,我们考虑插板法:把 \(m\) 拆成很多个 \(1\) ,插 \(n-1\) 个板算出来的就是每组大于0的方案,我们算\(m+n-1\) 的插板就可以了,因为之后我们每组 \(-1\) 就是一样的了。
#include<bits/stdc++.h>
#define int long long
#define pb push_back
#define lbt(x) (x&(-x))
using namespace std;
const int N=2e6+10,mod=1e9+7;
int n,m,q,T,jie[N],ni[N];
int ksm(int x,int k){
	int ans=1;
	while(k){
		if(k%2) ans=ans*x%mod;
		x=x*x%mod;k/=2;
	}return ans;
}
int solve(int x){
	int q=2,ans=1;
	while(x>1){
		if(q*q>m) return ans;
		int cnt=0;
		while(x%q==0){
			cnt++;x/=q;
		}cnt=cnt/2;
		ans=ans*(ksm(q,cnt));
		q++;
	}return ans;
}
int c(int n,int m){
	return jie[m]*((ni[n]*ni[m-n])%mod)%mod;
}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
    cin>>n>>m;m=solve(m);
	jie[1]=1; 
	for(int i=2;i<N;i++) jie[i]=jie[i-1]*i%mod;
	ni[N-1]=ksm(jie[N-1],mod-2);
	for(int i=N-2;i>=0;i--){
		ni[i]=ni[i+1]*(i+1)%mod;
	}
	cout<<c(n-1,m+n-1);
	return 0;
}
t2 久违的大模拟:
现在有一个数独的初始状态,出题人想对其进行一些修改和询问操作。需要注意:在操作时,初始状态中的数也可以被删除或者合并时被替换。
向目前状态中的指定位置填入一个数:但有可能这个位置已经有一个数了,此时你需要输出一行 Error!,然后不进行这次修改操作;在指定的 这个位置没有数的情况下,这个数已经与之前存在的在同一行、列或九宫格中的数构成冲突,此时,你需要按照行、列、九宫格的顺序,找到 第一种冲突的情况,输出一行Error:row! ,Error:column!或Error:square!,然后不进行这次修改操作;否则,你需要输出 OK!,并在指定位置填入该数。
删除目前状态中的一个位置上的数:若这个位置没有数字,此时你需要输出一行 Error!,然后不进行任何操作;否则你需要输出一行 OK!,并将该位置的数删除。
查询目前状态中的某个位置能填入多少种数字;若被查询的位置已经有数字了,你需要输出一行 Error!;否则,输出一行一个整数 n 表示能填入的数字个数,随后 n 行每行一个整数,按照从小到大的顺序输出能填入的数字。
将之前的第 i 次操作后的数独状态和第 j 次操作后的数独状态进行合并,作为当前状态。需要注意:对于所有的 5 种操作,包括但不限于出现 Error!或是没有进行任何修改,均被算作一次操作。合并时以行为第一关键字,列为第二关键字的顺序依次考虑每个格子,若第 i 次操作后的数独状态中该位置有数且不会与之前冲突则优先填入;否则,在不会与之前冲突的情况下,填入第 j 次操作后的数独状态中该位置的数。若均没有数字或均与本次合并中已填入的数字冲突,则不填入任何数。输出一行,包含空格隔开的两个整数,表示最终的结果中有多少数字来自第 i次操作后的数独状态中,多少来自第j 次操作后的数独状态中。
查询整个数独的状态,你需要使用方阵格式将整个数独目前的状态输出。方阵格式是一个 19×19 的二维字符数组,具体格式如下,其中用 0 表示 该位置还未填入数字。
没啥难度 一下子写完了:
#include<bits/stdc++.h>
using namespace std;
const int N=15; 
string s,l1={'+','-','+','-','+','-','+','-','+','-','+','-','+','-','+','-','+','-','+'};
int mp[N][N],n,cch[N],befmp[105][N][N];
void init(){
	cin>>s;
	for(int i=1;i<=9;i++){
		cin>>s;
		for(int j=1;j<=9;j++){
			mp[i][j]=int(s[1+2*(j-1)]-'0');
		}cin>>s;
	}cin>>n;
}
void pr(){
	cout<<l1<<'\n';
	for(int i=1;i<=9;i++){
		cout<<"|";
		for(int j=1;j<=9;j++){
			cout<<mp[i][j]<<"|";
		}cout<<'\n'<<l1<<'\n';
	}
}
void query(int x,int y){
	for(int i=1;i<=9;i++) cch[i]=0;
	if(mp[x][y]){
		cout<<"Error!\n";
		return;
	}
	for(int i=1;i<=9;i++){
		cch[mp[x][i]]=cch[mp[i][y]]=1;
	}
	for(int i=1;i<=3;i++){
		for(int j=1;j<=3;j++){
			int nx=i+(floor((x-1)/3)*3);
			int ny=j+(floor((y-1)/3)*3);
			cch[mp[nx][ny]]=1;
		}
	}int sum=0;
	for(int i=1;i<=9;i++){
		if(cch[i]==0) sum++;
	}cout<<sum<<'\n';
	for(int i=1;i<=9;i++){
		if(cch[i]==0) cout<<i<<'\n';
	}
}
void ins(int x,int y,int k){
	if(mp[x][y]){
		cout<<"Error!\n";
		return;
	}
	for(int i=1;i<=9;i++){
		if(mp[x][i]==k){
			cout<<"Error:row!\n";
			return;
		}
	}
	for(int i=1;i<=9;i++){
		if(mp[i][y]==k){
			cout<<"Error:column!\n";
			return;
		}
	}
	for(int i=1;i<=3;i++){
		for(int j=1;j<=3;j++){
			int nx=i+(int((x-1)/3))*3;
			int ny=j+(int((y-1)/3))*3;
			if(mp[nx][ny]==k){
				cout<<"Error:square!\n";
				return;
			}
		}
	}
	cout<<"OK!\n";
	mp[x][y]=k; 
}
void dele(int x,int y){
	if(mp[x][y]==0){
		cout<<"Error!\n";
		return;
	}cout<<"OK!\n";
	mp[x][y]=0;
}
int check(int x,int y,int k){
	for(int i=1;i<=9;i++){
		if(mp[x][i]==k){
			return 0;
		}
	}
	for(int i=1;i<=9;i++){
		if(mp[i][y]==k){
			return 0;
		}
	}
	for(int i=1;i<=3;i++){
		for(int j=1;j<=3;j++){
			int nx=i+(int((x-1)/3))*3;
			int ny=j+(int((y-1)/3))*3;
			if(mp[nx][ny]==k){
				return 0;
			}
		}
	}
	return 1;
}
void merge(int x,int y){
	int sum1=0,sum2=0;
	for(int i=1;i<=9;i++){
		for(int j=1;j<=9;j++){
			mp[i][j]=0;
		}
	}
	for(int i=1;i<=9;i++){
		for(int j=1;j<=9;j++){
			if(befmp[x][i][j]!=0&&check(i,j,befmp[x][i][j])){
				mp[i][j]=befmp[x][i][j];sum1++;
			}
			else if(befmp[y][i][j]!=0&&check(i,j,befmp[y][i][j])){
				mp[i][j]=befmp[y][i][j];sum2++;
			}
		}
	}
	cout<<sum1<<" "<<sum2<<'\n';
}
void solve(){
	for(int i=1;i<=n;i++){
		string opt;int x,y,k;
		cin>>opt;
		if(opt[0]=='Q'){
			cin>>x>>y;
			query(x,y);
		}
		else if(opt[0]=='I'){
			cin>>x>>y>>k;
			ins(x,y,k);
		}
		else if(opt[0]=='D'){
			cin>>x>>y;
			dele(x,y);
		}
		else if(opt[0]=='P'){
			pr();
		}
		else if(opt[0]=='M'){
			cin>>x>>y;
			merge(x,y);
		}
		for(int j=1;j<=9;j++){
			for(int k=1;k<=9;k++){
				befmp[i][j][k]=mp[j][k];
			}
		}
	}
}
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
    init();
    solve();
	return 0;
}
t3

输出0有 80pts 乱搞就过了 随机数据是这样的
t4

比较难 但是一个分组背包有 50 很快打完了。
没挂分是我??

                
            
        
浙公网安备 33010602011771号