列表

详情


NC223414. 科学幻想

描述

经过无数日夜的奋斗,疯狂科学家凤凰院凶真准备和助手克妮斯汀娜完成对时间机器某段代码的最后调试。已知这段代码是长度为的字符串,他的助手会给凶真下达条指令,指令一共有以下两种:
1:让凶真将第个字符修改为

2:询问凶真,区间的字符串与区间的字符串是否勉强相等。

凶真认为,若两个字符串长度相等,且两个字符串对应位置上最多有一个位置的字符不同,则这两个字符串勉强相等。例如:aaa与aaa、aab、aba、baa这四个字符串均勉强相等,但是aaa与abb不能算勉强相等。

凶真知道字符串中的字符从始至终只有小写字母这个类型,请问凶真对每个2类型指令的回答。

输入描述

第一行两个正整数,,其中,

第二行一个长度为的字符串。

接下来行,每行第一个整数表示指令类型,

,输入正整数与字符,其中

,输入正整数,,,,其中,

输出描述

输出凶真对每个2类型指令的回答,若勉强相等输出YES,否则输出NO。

示例1

输入:

6 3
abcaec
2 1 3 4 6
1 3 z
2 1 3 4 6

输出:

YES
NO

原站题解

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

C++ 解法, 执行用时: 121ms, 内存消耗: 2420K, 提交时间: 2021-07-21 22:57:11

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

const int N=1e5+10;
const int maxn=1e5;

ull H[N];
ull t[N];
char s[N];

inline int lowbit(int x){
	return x&-x;
}
ull getsum(int x){
	ull res=0;
	for(int i=x;i>0;i-=lowbit(i)){
		res+=t[i];
	}
	return res;
}
void add(int x,ull y){
	for(int i=x;i<=maxn;i+=lowbit(i)){
		t[i]+=y;
	}
}
bool check(int l1,int r1,int l2,int r2){
	ull res1=getsum(r1)-getsum(l1-1);
	ull res2=getsum(r2)-getsum(l2-1);
	if(l1<=l2){
		return res1*H[l2-l1]==res2;
	}
	else{
		return res2*H[l1-l2]==res1;
	}
}
int main()
{
	int seed=31;
	H[0]=1;
	for(int i=1;i<=100000;i++){
		H[i]=H[i-1]*seed;
	}
	int n,m;
	scanf("%d%d",&n,&m);
	scanf("%s",s+1);
	for(int i=1;i<=n;i++){
		add(i,(s[i]-'a')*H[i]);
	}
	for(int i=1;i<=m;i++){
		int op;
		scanf("%d",&op);
		if(op==1){
			int x;
			char c[3];
			scanf("%d%s",&x,c);
			add(x,-(s[x]-'a')*H[x]);
			s[x]=c[0];
			add(x,(s[x]-'a')*H[x]);
		}
		else{
			int l1,r1,l2,r2;
			scanf("%d%d%d%d",&l1,&r1,&l2,&r2);
			if(r1-l1!=r2-l2){
				printf("NO\n");
				continue;
			}
			int l=1,r=r1-l1+1,mid;
			while(l<=r){
				mid=(l+r)>>1;
				if(check(l1,l1+mid-1,l2,l2+mid-1)){
					l=mid+1;
				}
				else r=mid-1;
			}
			if(l==r1-l1+2){
				printf("YES\n");
				continue;
			}
			int pos=r+1;
			if(check(l1+pos,r1,l2+pos,r2)){
				printf("YES\n");
			}
			else printf("NO\n");
		}
	}
	return 0;
}

上一题