2024昆明邀请赛持续补题

E

前缀的值只有logX,对于每个值的最后一个选取为l-1,枚举r即可o(logX)复杂度

#include<bits/stdc++.h>
using namespace std; 
#define int long long
const int N=1e6+6;
int mod=1e9+7;
int a[N];
int suf[N];
void solve() {
	int n,k;
	cin>>n>>k;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	int now=0;
	for(int i=n;i>=1;i--){
		now=__gcd(now,a[i]);
		suf[i]=now;
	}
	suf[n+1]=0;
	int ans=suf[1];
	int pre=a[0];
	for(int i=0;i<=n;i++){
		if(__gcd(pre,a[i])==pre&&i!=n){
			continue;
		}
		//cout<<a[i]<<'\n';
		int gd1=0;
		int pre1=a[i];
		for(int j=i;j<=n;j++){
			gd1=__gcd(gd1,abs(a[j]-pre1));
			int sum1=__gcd(pre,gd1);
			int sum2=__gcd(a[i]+k,suf[j+1]);
		//	cout<<"i="<<i<<' '<<gd1<<'\n';
			ans=max(ans,__gcd(sum1,sum2));
			pre1=a[j];
		}
		pre=__gcd(pre,a[i]);
	}
	cout<<ans<<'\n';
}
signed main(){
	
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	int t = 1;
	cin >> t;
	while(t--){
		solve();
	}
	return 0;
}

M

类似于旋转卡壳,双指针枚举(记得开int128)

F

dijkstra+rmq

#include<bits/stdc++.h>
using namespace std; 
#define int long long
const int N=1e6+6;
int mod=1e9+7;
int n,m,k;
struct node{
	int v,c,l;
};
int a[N],b[N];
vector<node>g[N];
vector<int>color[N];
int vis[N];
struct node1{
	int r,d,u;
	bool operator <(const node1 &b)const{
		if(b.r!=r) return b.r<r;
		return b.d<d;
	}
};

struct nodek{
	int a,b,id;
}p[N];
bool cmp(nodek a,nodek b){
	if(a.a!=b.a)return a.a<b.a;
	return a.id<b.id;
}
int dp[N][64];
int l1[N],r1[N];
void rmq_init()
{
	for(int i=1;i<=k;i++){
		l1[p[i].a]=min(l1[p[i].a],i);
		r1[p[i].a]=max(r1[p[i].a],i);
	}
	for(int i=1;i<=k;i++)
		dp[i][0]=p[i].b;
	for(int j=1;(1ll<<j)<=k;j++)
		for(int i=1;i+(1ll<<j)-1<=k;i++)
			dp[i][j]=max(dp[i][j-1],dp[i+(1ll<<j-1)][j-1]);
}
int rmq(int l,int r)
{
	int kk=log2(r-l+1);
	return max(dp[l][kk],dp[r-(1<<(kk))+1][kk]);
}

void dij(){
	priority_queue<node1>q;
	for(int i=1;i<=n;i++){
		vis[i]=0;
	}
	q.push({1,0,1});
	while(q.size()){
		
		auto [r,d,u]=q.top();
		//	cout<<r<<' '<<d<<' '<<u<<'\n';
		q.pop();
		if(vis[u]==1) continue;
		vis[u]=1;
		for(node x:g[u]){
			if(vis[x.v]==1)continue;
			if(x.c==a[r]&&d+x.l<=b[r]){
				q.push({r,d+x.l,x.v});
			}
			else{
					int le=l1[x.c],re=r1[x.c];
					int now=-1;
					while(le<=re){
						int mid=(le+re)>>1;
						if(p[mid].id<=r){
							le=mid+1;
						}
						else{
							re=mid-1;
						}
					}
					int le1=re+1,re1=r1[x.c];
				int st=le1;
				while(le1<=re1){
					int mid=(le1+re1)>>1;
					if(rmq(st,mid)<x.l){
						le1=mid+1;
					}
					else{
						now=mid;
						re1=mid-1;
					}
				}
					if(now!=-1){
						q.push({p[now].id,x.l,x.v});
					}
				}
			}
		}
	
}
void solve() {
	cin>>n>>m>>k;
	for(int i=1;i<=n;i++){
		g[i].clear();
	}
	for(int i=1;i<=m;i++){
		l1[i]=1e18;
		r1[i]=0;
	}
	for(int i=1;i<=m;i++){
		int u,v,c,l;
		cin>>u>>v>>c>>l;
		
		g[u].push_back({v,c,l});
		g[v].push_back({u,c,l});
	}
	for(int i=1;i<=k;i++){
		cin>>a[i]>>b[i];
		p[i].a=a[i];
		p[i].b=b[i];
		p[i].id=i;
	}
	sort(p+1,p+k+1,cmp);
	rmq_init();
	dij();
	for(int i=1;i<=n;i++){
		if(vis[i]){
			cout<<1;
		}
		else{
			cout<<0;
		}
	}
	cout<<'\n';
	
}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	int t = 1;
	cin >> t;
	while(t--){
		solve();
	}
	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值