其他分享
首页 > 其他分享> > Codeforces Round #742 (Div. 2)

Codeforces Round #742 (Div. 2)

作者:互联网

MEXor Mixup

m e x mex mex意思就是不在集合里面最小的正整数.所以给出一个 m e x mex mex那么他前面的所有的东西都是要选上的,然后前面的这些所有的异或之和(假设为 x x x)就可以预处理然后用 O 1 O1 O1的计算出来,因为给出的必须异或和为 y y y,所以我们还差一个 z = x   x o r   y z=x\ xor \ y z=x xor y,也就是 z   x o r   x = y z \ xor \ x=y z xor x=y,然后就是分情况了:

#include<cstdio>
#include<algorithm>
#include<cstring>
#define maxn 400000
using namespace std;
int T,a[maxn],x,y;
signed main(){
	scanf("%d",&T);
	for(int i=1;i<=300000;i++) a[i]=a[i-1]^i;
	while(T--){
		scanf("%d %d",&x,&y);
		if(a[x-1]==y) {printf("%d\n",x);continue;}
		int temp=a[x-1]^y;
		if(temp>x) printf("%d\n",x+1);
		else if(temp==x) printf("%d\n",x+2);
		else printf("%d\n",x+1);
	}
	return 0;
}

Carrying Conundrum

这个题目的进位方式有一点奇怪,他是进到下下位去的.

106 = 0 + 106        = 1 + 105 . . . . . . . . . . . . .        = 106 + 0 106=0+106\\ \ \ \ \ \ \ =1+105\\.............\\ \ \ \ \ \ \ =106+0 106=0+106      =1+105.............      =106+0

#include<cstdio>
#include<algorithm>
#include<cstring>
#define maxn 50
#define int long long
using namespace std;
int T,n,dp[maxn],a[maxn];
signed main(){
	scanf("%lld",&T);
	while(T--){
		scanf("%lld",&n);
		int k=0; memset(dp,0,sizeof dp);
		while(n){
			a[++k]=n%10;
			n/=10;
		}
		int temp1=0,temp2=0;
		for(int i=k;i;i--){
			if(i%2) temp1=temp1*10+a[i];
			else temp2=temp2*10+a[i];
		}
		if(temp1==0 || temp2==0) printf("%lld\n",temp1+temp2-1);
		else{
			printf("%lld\n",(temp2+1)*(temp1+1)-2);
		}
	}
	return 0;
}

Expression Evaluation Error

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
int T,n,m;
signed main(){
	scanf("%d",&T);
	while(T--){
		scanf("%d %d",&n,&m);
		for(int i=1;i<m;i++){
			double temp=pow(10,(int)log10(n-(m-i)));
			printf("%.0f ",temp); n-=temp;
		}
		printf("%d\n",n);
	}
	return 0;
}

Non-Decreasing Dilemma

单点修改,区间查询,比较显然是要用数据结构的,这里要用到线段树合并,以前如果没有做过类似的题目的话是比较难想到的.

u.lval=l.lval; u.rval=r.rval;
u.lmax=l.lmax; u.rmax=r.rmax;
u.len=l.len+r.len; u.sum=l.sum+r.sum;

其他的就简单了,注意 q u e r y query query得用 n o d e node node形式,因为答案要用 m e r g e merge merge得到的答案,而不是 l . s u m + r . s u m l.sum+r.sum l.sum+r.sum.

#include<cstdio>
#include<algorithm>
#include<cstring>
#define maxn 200010
#define int long long
using namespace std;
int n,q,a[maxn];
struct node{
	int sum,lmax,rmax,len,lval,rval;
}tree[maxn<<2];
void modify(node &x,int temp){
	x.len=x.sum=x.lmax=x.rmax=1;
	x.lval=x.rval=temp;
}
node merge(node l,node r){
	node u;
	u.lval=l.lval; u.rval=r.rval;
	u.lmax=l.lmax; u.rmax=r.rmax;
	u.len=l.len+r.len; u.sum=l.sum+r.sum;
	if(l.rval<=r.lval){
		if(l.lmax==l.len) u.lmax+=r.lmax;
		if(r.rmax==r.len) u.rmax+=l.rmax;
		u.sum+=l.rmax*r.lmax;
	}
	return u;
}
void build(int id,int l,int r){
	if(l==r) {modify(tree[id],a[l]); return ;}
	build(id*2,l,l+r>>1),build(id*2+1,(l+r>>1)+1,r);
	tree[id]=merge(tree[id*2],tree[id*2+1]);
}
void update(int id,int l,int r,int x,int val){
	if(l==r) {modify(tree[id],val); return ;}
	int mid=l+r>>1;
	if(mid>=x) update(id*2,l,mid,x,val);
	else update(id*2+1,mid+1,r,x,val);
	tree[id]=merge(tree[id*2],tree[id*2+1]);
}
node query(int id,int l,int r,int ll,int rr){
	if(l==ll && r==rr) return tree[id];
	int mid=l+r>>1;
	if(mid>=rr) return query(id*2,l,mid,ll,rr);
	else if(ll>mid) return query(id*2+1,mid+1,r,ll,rr);
	else return merge(query(id*2,l,mid,ll,mid),query(id*2+1,mid+1,r,mid+1,rr));
}
signed main(){
	scanf("%lld %lld",&n,&q);
	for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
	build(1,1,n);
	for(int i=1,opt,l,r;i<=q;i++){
		scanf("%lld %lld %lld",&opt,&l,&r);
		if(opt==1) update(1,1,n,l,r);
		if(opt==2) printf("%lld\n",query(1,1,n,l,r).sum);
	}
	return 0;
}

题解发的很晚,见谅,快开学了,更新的比较慢,但是我会努力的.

标签:742,int,sum,rmax,Codeforces,lmax,Div,id,1000
来源: https://blog.csdn.net/qq_44590230/article/details/120296445