pyyzDay9

简单的模拟赛(挂大分)

T1

image

32<=n<=60,T<=1000

考虑直接将数给算出来

判断每一位是否为1

只需要判断当前的数按位与的结果是否为0

注意每次操作完都要更改数值符合sgn数组

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iomanip>
#include<bits/stdc++.h>
#define int long long
#define jiaa(a,b) {a+=b;if(a>=MOD) a-=MOD;}
#define jian(a,b) {a-=b;if(a<0) a+=MOD;}
using namespace std;
inline int read()
{
	int x=0,f=1;char ch=getchar();
	while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
	while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
	return x*f;
}
int sgn[65],a[65],b[65],ans[65],sec[65];
signed main()
{
	//freopen("filename.in", "r", stdin);
	//freopen("filename.out", "w", stdout);
	int n;
	cin>>n;
	sec[0]=1;
	for(int i=1;i<=60;i++) sec[i]=sec[i-1]*2;
	for(int i=0;i<n;i++) cin>>sgn[i];
	int T;
	cin>>T;
	while(T--){
		for(int i=0;i<n;i++){
			cin>>a[i];
			ans[i]=0;
		}
		for(int i=0;i<n;i++) cin>>b[i];
		int an=0;
		for(int i=0;i<n;i++){
			an+=a[i]*sgn[i]*sec[i];
			an+=b[i]*sgn[i]*sec[i];
		}
		for(int i=0;i<n;i++){
			if(an&(sec[i+1]-1)){
				ans[i]++;
				an-=sgn[i]*sec[i];
			}
		}
		for(int i=0;i<n;i++) cout<<ans[i]<<' ';
		cout<<'\n';
	}
	return 0;
}

T2

image

n,m<=100000

考虑最小生成树是一条链的情况一定不劣

维护相邻点边的minn即可

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iomanip>
#include<bits/stdc++.h>
#define int long long
#define jiaa(a,b) {a+=b;if(a>=MOD) a-=MOD;}
#define jian(a,b) {a-=b;if(a<0) a+=MOD;}
using namespace std;
int ksm(int a,int b,int p){
	if(b==0) return 1;
	if(b==1) return a%p;
	int c=ksm(a,b/2,p);
	c=c*c%p;
	if(b%2==1) c=c*a%p;
	return c%p;	
}
inline int read()
{
	int x=0,f=1;char ch=getchar();
	while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
	while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
	return x*f;
}
struct node{
	int l,r,w;
}tr[100005];
int cha[100005];
vector<int> bian[100005];
multiset<int> minn;
signed main()
{
	//freopen("filename.in", "r", stdin);
	//freopen("filename.out", "w", stdout);
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		cin>>tr[i].l>>tr[i].r>>tr[i].w;
		cha[tr[i].l]++;
		cha[tr[i].r+1]--;
		bian[tr[i].l].push_back(tr[i].w);
		bian[tr[i].r].push_back(-tr[i].w);
	}
	for(int i=1;i<=n;i++){
		cha[i]+=cha[i-1];
		if(!cha[i]){
			cout<<-1<<'\n';
			return 0;
		}
	}
	int ans=0;
	for(int i=1;i<n;i++){
		for(auto ed:bian[i]){
			if(ed>0) minn.insert(ed);
			else minn.erase(minn.find(-ed));
		}
		ans+=*minn.begin();
	}	
	cout<<ans<<'\n';
	return 0;
}

T3

image

n,m<=200000

考虑类似最短路的做法

发现每条边的边权是可变的

于是记录 dis(ei,u) 表示通过边 ei 到达 u 节点时的最短路径长度

对于两条边a_ex,a_ey,若a_ex<a_ey&&dis(ex,u)<dis(ey,u) 则ey这条边一定无用

具体的,先对每个点能到达的所有点的边权排序

若先后更新的两条边是a_eq,a_qp,只会对边权在a_ep~a_eq之间的产生影响

二分查找两端即可

然后dij

注意松弛操作不超过2次

故复杂度正确

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iomanip>
#include<bits/stdc++.h>
#define int long long
#define jiaa(a,b) {a+=b;if(a>=MOD) a-=MOD;}
#define jian(a,b) {a-=b;if(a<0) a+=MOD;}
#define pii pair<int,pair<int,int> >
using namespace std;
int ksm(int a,int b,int p){
	if(b==0) return 1;
	if(b==1) return a%p;
	int c=ksm(a,b/2,p);
	c=c*c%p;
	if(b%2==1) c=c*a%p;
	return c%p;	
}
inline int read()
{
	int x=0,f=1;char ch=getchar();
	while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
	while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
	return x*f;
}
vector<pii > tu[200005];
priority_queue<pii ,vector<pii >,greater<pii > > hp;
int las[200005],ans[200005];
const int inf=1e16;
signed main()
{
	//freopen("filename.in", "r", stdin);
	//freopen("filename.out", "w", stdout);
	int n=read(),m=read();
	for(int i=1;i<=m;i++){
		int u=read(),v=read(),a=read(),b=read();
		tu[u].push_back({a,{b,v}});
	}
	for(int i=1;i<=n;i++){
		las[i]=ans[i]=inf;
		sort(tu[i].begin(),tu[i].end());
	} 
	hp.push({0,{1,inf-1}});
	while(!hp.empty()){
		int sum=hp.top().first;
		int u=hp.top().second.first;
		int la=hp.top().second.second;
		hp.pop();
		ans[u]=min(ans[u],sum);
		if(la>=las[u]) continue;
		if(las[u]==inf){
			for(auto v:tu[u]){
				int su=sum;
				int a=v.first;
				int b=v.second.first;
				int ed=v.second.second;
				if(a>la) su+=a-b;
				else su+=a;
				hp.push({su,{ed,a}});
			}
		}
		else{
			int l=upper_bound(tu[u].begin(),tu[u].end(),pii{la+1,{0,0}})-tu[u].begin();
			for(int i=l;i<tu[u].size();i++){
				int a=tu[u][i].first;
				int b=tu[u][i].second.first;
				int ed=tu[u][i].second.second;
				if(a>las[u]) break;
				hp.push({sum+a-b,{ed,a}});
			}
		}
		las[u]=la;
	}
	for(int i=1;i<=n;i++){
		if(ans[i]==inf) cout<<-1<<' ';
		else cout<<ans[i]<<' ';
	}
	return 0;
}

T4

image

n,q<=100000
ai,v<=10000

注意到加减和后缀乘操作都可以被消掉

对答案有贡献的只有前缀连续乘

只需枚举前缀乘的长度

答案贡献为前缀乘积×(2×3^(n-1-len))(后面需要紧接着+/-,其余符号+/-/*)

考虑每次操作

只对i~n的答案有影响

答案变化为乘v/ai(需要逆元)

相当于后缀乘

维护线段树即可

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iomanip>
#include<bits/stdc++.h>
#define int long long
using namespace std;
int ksm(int a,int b,int p){
	if(b==0) return 1;
	if(b==1) return a%p;
	int c=ksm(a,b/2,p);
	c=c*c%p;
	if(b%2==1) c=c*a%p;
	return c%p;	
}
inline int read(){
	int x=0,f=1;char ch=getchar();
	while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
	while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
	return x*f;
}
void out(int x){
	if(x<0)putchar('-'),x=-x;
	if(x<10)putchar(x+'0');
	else out(x/10),putchar(x%10+'0');
}
int n,m,q,a[100001],ll[500001],rr[500001],tagch[500001],sum[500001],an[500005],thi[100005];
int ls(int x){
	return x<<1;
} 
int rs(int x){
	return x<<1|1;
}
void pushup(int x){
	sum[x]=(sum[ls(x)]+sum[rs(x)])%m;
}
void build(int x,int l,int r){
	ll[x]=l,rr[x]=r;
	tagch[x]=1;
	if(l==r){
		sum[x]=an[l]%m;
		return;
	}
	int mid=(l+r)>>1;
	build(ls(x),l,mid),build(rs(x),mid+1,r);
	pushup(x);
}
void tag_cheng(int x,int tag){
	(sum[x]*=tag)%=m;
	(tagch[x]*=tag)%=m;
}
void pushdown(int x){
	if(tagch[x]!=1){
		tag_cheng(ls(x),tagch[x]);
		tag_cheng(rs(x),tagch[x]);
		tagch[x]=1;
	}
}
void add_cheng(int x,int L,int R,int k){
	if(L<=ll[x]&&rr[x]<=R) return tag_cheng(x,k);
	pushdown(x);
	int mid=(ll[x]+rr[x])>>1;
	if(L<=mid) add_cheng(ls(x),L,R,k);
	if(mid<R) add_cheng(rs(x),L,R,k);
	pushup(x);
}
int query(int x,int L,int R){
	if(L<=ll[x]&&rr[x]<=R) return sum[x];
	pushdown(x);
	int mid=(ll[x]+rr[x])>>1;
	int ret=0;
	if(L<=mid) (ret+=query(ls(x),L,R))%=m;
	if(mid<R) (ret+=query(rs(x),L,R))%=m;
	return ret;
}
signed main(){
	cin>>n>>q;
	m=1000000007;
	for(int i=1;i<=n;i++) cin>>a[i];
	thi[0]=1;
	for(int i=1;i<=n;i++){
		thi[i]=thi[i-1]*3%m;
	}
	int ch=1;
	for(int i=1;i<=n;i++){
		ch=ch*a[i]%m;
		if(i==n) an[i]=ch;
		else an[i]=ch*2%m*thi[n-1-i]%m;
	}
	build(1,1,n);
	while(q--){
		int t,v;
		cin>>t>>v;
		int su=a[t];
		su=ksm(a[t],m-2,m);
		su=su*v%m;
		add_cheng(1,t,n,su);
		cout<<query(1,1,n)<<'\n';
		a[t]=v;
	}
	return 0;	
}
posted @ 2025-08-13 17:22  gbrrain  阅读(12)  评论(6)    收藏  举报