列表

详情


NC240728. 牵一半

描述

这生命 无常又孤单
你的存在 是我唯一依赖
失去的梦 伤过的心
该怎么去 补完
有些困惑 这一生 我们都不知道答案
我错过太多美满
留过太多遗憾
而在这一次 我想要抓住
那份期盼
————《牵一半》阿良良木健(侵删)

定义函数f(x,p)(p为质数)为,当x不是p的倍数时,f(x,p)x 在模 p意义下的乘法逆元(即),xp的倍数时

阿良良木健现在有一个序列长度为n的序列a_i,和m个操作。

操作有两种:

a_x更改为y

,求max(f(a_i,p))其中

保证数据随机

随机方式如下:

a_i,x,y中的正整数中 等概率随机生成

opt(指操作序号)中随机生成

l,r中的正整数中 等概率随机生成 生成后若 则交换 l,r

p的质数中 等概率随机生成一个

输入描述

第一行,两个正整数

后面一行,每行 n 个数,表示序列 a

后面 m 行,每行三个或四个数,表示一次操作

输出描述

对于每个操作2,输出一行一个非负整数,表示这一询问的答案。

示例1

输入:

10 10
5 6 2 8 9 8 7 8 1 3
2 3 8 5
1 2 6
2 7 8 7
2 7 8 2
1 3 9
2 5 8 3
1 2 7
1 9 8
2 1 4 7
2 4 6 7

输出:

4
1
1
2
4
4

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(g++ 7.5.0) 解法, 执行用时: 2438ms, 内存消耗: 51012K, 提交时间: 2022-09-02 20:41:45

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

int ksm(ll a,ll p,ll M){ll res=1;while(p){if(p&1){res=res*a%M;}a=a*a%M;p>>=1;}return res;}
int i,j,k,n,m,t,a[500500],res;
set<int> s[500500];

int main(){
	ios::sync_with_stdio(0);cin.tie(0);
	
	cin>>n>>t;
	for(i=1;i<=n;i++){
		cin>>a[i];
		s[a[i]].insert(i);
	}
	while(t--){
		int op,l,r,p;
		cin>>op>>l>>r;
		if(op==1){
			s[a[l]].erase(l);
			a[l]=r;
			s[a[l]].insert(l);
		}
		else{
			cin>>p;res=0;
			for(i=p-1;i>=1;i--){
				int t=ksm(i,p-2,p);
				for(j=t;j<=n;j+=p){
					if(s[j].empty())continue;
					auto it=s[j].lower_bound(l);
					if(it!=s[j].end()&&(*it)<=r){
						res=i;goto aaa;
					}
				}
			}
			aaa:;
			cout<<res<<'\n';
		}
	}
}

C++(clang++ 11.0.1) 解法, 执行用时: 2500ms, 内存消耗: 50976K, 提交时间: 2022-09-02 21:23:46

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int M=5e5+7;
int n,m,a[M],op,x,y,p,nw;
set<int> se[M];
int ksm(ll a,int b,int Mod){
	ll ans=1;
	while(b){
		if(b&1) ans=ans*a%Mod;
		a=a*a%Mod,b>>=1;
	}
	return (int)ans;
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]),
		se[a[i]].insert(i);
	while(m--){
		scanf("%d%d%d",&op,&x,&y);
		if(op==1)
			se[a[x]].erase(x),a[x]=y,
			se[a[x]].insert(x);
		else{
			scanf("%d",&p);
			for(int i=p-1;i>=1;i--){
				nw=ksm(i,p-2,p);
				for(int j=nw;j<=n;j+=p)
					for(auto k:se[j])
						if(x<=k && k<=y){
							printf("%d\n",i);
							goto fin;
						}
			}
			puts("0");
			fin:;
		}
	}
	return 0;
}

上一题