noip模拟72

考场

早上去上了语文课,于是回来选择只写两道题
t1 看错了题没看见只能一个一个往里加于是主动弃掉
t2 看起来像是一个二维树状数组就可以做的题(然而没有意识到模数不互质的严重性)
t3 以为有单调性二分加哈希就可以了,于是先写 t3,写完才发现问题所在,看起来像是后缀类的科技,直接放弃
t4 没看


A. T1 出了个大阴间题

一看范围是状压,数是一个一个往里加的,这就提供一个很好的性质:与 b 产生过程无关,其贡献可以直接计算
f[S][i] 表示已选集合为 S,且 a 的值为 j
显然开不下,然而发现性质只可能比集合 max1 或相等,所以开两维即可
分别记录真实的 a 值,排列方案数,以及此时总和

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=1e6+5;
const int mod=1e9+7;
const int maxm=40;
int n,a[maxm],all,m,val[maxm],sum[maxm],ans;
int f[maxn][maxm];//值
int g[maxn][maxm];//排列个数
int h[maxn][maxm];//和
int read(){
	int x=0,f=1;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
	while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}
	return x*f;
}
void modadd(int &a,int b){
	a=(a+b)%mod;
}
signed main(){
	freopen("repair.in","r",stdin);
	freopen("repair.out","w",stdout);
	n=read();m=read();
	for(int i=1;i<=n;i++)a[i]=read();
	for(int i=1;i<=n;i++)val[i]=val[i-1]*2+1,sum[i]=sum[i-1]+val[i];
	all=(1<<n)-1;
	for(int i=1;i<=n;i++)f[1<<(i-1)][0]=a[i],g[(1<<(i-1))][0]=1;
	for(int i=1;i<=all;i++){
		if(!f[i][0])continue;
		for(int j=1;j<=n;j++){
			if((1<<(j-1))&i)continue;
			int S=(i|(1<<(j-1)));
			for(int k=0;k<=1;k++){
				if(!f[i][k])continue;
				int nxt=(f[i][k]==a[j])?a[j]+1:max(f[i][k],a[j]);
//				cout<<nxt<<endl;
				if(nxt<f[S][0]){
					if(nxt>f[S][1])f[S][1]=nxt,g[S][1]=h[S][1]=0;
					if(nxt==f[S][1]){
						modadd(g[S][1],g[i][k]);
						modadd(h[S][1],nxt*g[i][k]%mod+h[i][k]);
					}
				}
				else{
					if(nxt>f[S][0]){
						f[S][1]=f[S][0],g[S][1]=g[S][0],h[S][1]=h[S][0];
						f[S][0]=nxt,g[S][0]=h[S][0]=0;
					}
					if(nxt==f[S][0]){
						modadd(g[S][0],g[i][k]);
						modadd(h[S][0],nxt*g[i][k]%mod+h[i][k]);
					}
				}
			}
//			cout<<f[S][0]<<" "<<g[S][0]<<" "<<h[S][0]<<endl;
		}
	}
	ans=(h[all][0]*m%mod+g[all][0]*sum[n-2]%mod)%mod;
	cout<<f[all][0]<<" "<<ans;
	return 0;
}

B. T2 最简单辣快来做

由于模数不互质,不能提前预处理负幂次
考虑进行二维前缀和
把关键点形成的网格拿出来处理四个方向的前缀和,然后将询问点推到网格整点进行加减计算
注意预处理次方,否则得写光速幂

代码实现
#include<bits/stdc++.h>
using namespace std;
const int maxn=3005;
int n,t,ll,rr,mod,a,b,totx,toty,x[maxn],y[maxn],sum[maxn][maxn][4],h[maxn],px[maxn],py[maxn],xx,yy,lx[maxn],ly[maxn];
int pos[maxn][maxn];
int read(){
	int x=0,f=1;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
	while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}
	return x*f;
}
void modadd(int &a,int b){
	a=(a+b)%mod;
	return ;
}
int po(int a,int b){
	if(b<0)return 0;
	int ans=1;
	while(b){
//		cout<<a<<" "<<b<<endl;
		if(b&1)ans=1ll*ans*a%mod;
		a=1ll*a*a%mod;
		b>>=1;
	}
	return ans;
}
int main(){
	freopen("satellite.in","r",stdin);
	freopen("satellite.out","w",stdout);
	n=read(),t=read(),ll=read(),rr=read(),mod=read(),a=read(),b=read();
	for(int i=1;i<=n;i++){
		h[i]=read();
		lx[i]=x[i]=read();
		ly[i]=y[i]=read();
	}
	lx[n+1]=ll,ly[n+1]=rr;
	sort(lx+1,lx+n+2);totx=unique(lx+1,lx+n+2)-lx-1;
	sort(ly+1,ly+n+2);toty=unique(ly+1,ly+n+2)-ly-1;
	for(int i=1;i<=n;i++){
		x[i]=lower_bound(lx+1,lx+totx+1,x[i])-lx;
		y[i]=lower_bound(ly+1,ly+toty+1,y[i])-ly;
		modadd(pos[x[i]][y[i]],h[i]);
	}
	for(int i=1;i<=totx+1;i++)px[i]=po(a,lx[i]-lx[i-1]);
	for(int i=1;i<=toty+1;i++)py[i]=po(b,ly[i]-ly[i-1]);
//	cout<<"hhh "<<endl;
	for(int i=1;i<=totx;i++){
		for(int j=1;j<=toty;j++){
			int res=0;
			modadd(res,1ll*sum[i-1][j][0]*px[i]%mod);
			modadd(res,1ll*sum[i][j-1][0]*py[j]%mod);
			modadd(res,mod-1ll*sum[i-1][j-1][0]*px[i]%mod*py[j]%mod);
			modadd(res,pos[i][j]);sum[i][j][0]=res;
		}
	}
	for(int i=1;i<=totx;i++){
		for(int j=toty;j>=1;j--){
			int res=0;
			modadd(res,1ll*sum[i-1][j][1]*px[i]%mod);
			modadd(res,1ll*sum[i][j+1][1]*py[j+1]%mod);
			modadd(res,mod-1ll*sum[i-1][j+1][1]*px[i]%mod*py[j+1]%mod);
			modadd(res,pos[i][j]);sum[i][j][1]=res;
		}
	}
	for(int i=totx;i>=1;i--){
		for(int j=1;j<=toty;j++){
			int res=0;
			modadd(res,1ll*sum[i+1][j][2]*px[i+1]%mod);
			modadd(res,1ll*sum[i][j-1][2]*py[j]%mod);
			modadd(res,mod-1ll*sum[i+1][j-1][2]*px[i+1]%mod*py[j]%mod);
			modadd(res,pos[i][j]);sum[i][j][2]=res;
		}
	}
	for(int i=totx;i>=1;i--){
		for(int j=toty;j>=1;j--){
			int res=0;
			modadd(res,1ll*sum[i+1][j][3]*px[i+1]%mod);
			modadd(res,1ll*sum[i][j+1][3]*py[j+1]%mod);
			modadd(res,mod-1ll*sum[i+1][j+1][3]*px[i+1]%mod*py[j+1]%mod);
			modadd(res,pos[i][j]);sum[i][j][3]=res;
		}
	}
//	for(int i=0;i<=3;i++)cout<<sum[2][2][i]<<" ";
//	puts("");
	while(t--){
		xx=read(),yy=read();
		int posx=lower_bound(lx+1,lx+totx+1,xx)-lx;
		int posy=lower_bound(ly+1,ly+toty+1,yy)-ly;
		int pox1=po(a,xx-lx[posx-1]),pox2=po(a,lx[posx]-xx),poy1=po(b,yy-ly[posy-1]),poy2=po(b,ly[posy]-yy),res=0;
		modadd(res,1ll*pox1*poy1%mod*sum[posx-1][posy-1][0]%mod);
		modadd(res,1ll*pox1*poy2%mod*sum[posx-1][posy][1]%mod);
		modadd(res,1ll*pox2*poy1%mod*sum[posx][posy-1][2]%mod);
		modadd(res,1ll*pox2*poy2%mod*sum[posx][posy][3]%mod);
		printf("%d\n",res);
	}
	return 0;
}

C. T3 是我的你不要抢

考虑根号分治,大于 n 不超过 n ,可以两两处理的总复杂度是 nn 的,记忆化一下
其余的单次 n 处理即可


D. T4 显然也是我整的

神仙题,下次碰见还想不出来……
搬篇巨佬的题解:
捕获.PNG

其实不用用 set,直接小根堆维护即可

代码实现
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=2e5+5;
int n,m,x,sta[maxn],tp,t;
int read(){
	int x=0,f=1;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
	while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}
	return x*f;
}
priority_queue<int,vector<int>,greater<int> >q;
int gcd(int a,int b){return a==0?b:gcd(b%a,a);}
int solve(int n){
	int res=0,g=0;
	if(q.top()>n/2){
		int nxt=2*q.top()-n;
		n-=nxt;res+=nxt;
		while(!q.empty())sta[++tp]=q.top(),q.pop();
		while(tp)q.push(sta[tp--]-nxt);
	}
	while(!q.empty()&&q.top()<=n/2){
		g=gcd(g,q.top());
		q.pop();
	}
	while(!q.empty()&&q.top()+g<=n){
		g=gcd(g,q.top());q.pop();
	}
	if(q.empty())return res+g;
	int ans=g+n%g;
	while(!q.empty())sta[++tp]=q.top(),q.pop();
	while(tp)q.push(sta[tp--]+ans-n);
	q.push(g);
	return res+solve(ans);
}
signed main(){
	freopen("graph.in","r",stdin);
    freopen("graph.out","w",stdout);
	t=read();
	while(t--){
		n=read(),m=read();
		for(int i=1;i<=m;i++)x=read(),q.push(x);
		printf("%lld\n",solve(n));
	}
	return 0;
}
posted @   y_cx  阅读(102)  评论(2编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示