P4440 [COCI2017-2018#3] Programiranje

题目描述

Little Leticija is preparing for a programming exam. Even though she has solved a lot of tasks, there’s one still left unsolved, so she is asking you for help. You are given the word S and Q queries. In each query, you are given positive integers A, B, C and D. Let’s say that word X consists of letters between positions A and B in word S, and word Y from letters between positions C and D in word S. For each query, you must answer if it is possible to somehow rearrange the letters in word Y and obtain word X.

输入格式

The first line of input contains the word S (1 ≤ |S| ≤ 50 000). |S| denotes the number of characters in word S, which consists of lowercase letters of the English alphabet. The second line of input contains the positive integer Q (1 ≤ Q ≤ 50 000).

Each of the following Q lines contains four integers A, B, C i D (1 ≤ A ≤ B ≤ |S| and 1 ≤ C ≤ D ≤ |S| ) from the task.

输出格式

For each query, output “DA” (Croatian for yes) if it is possible, and “NE” (Croatian for no) if it is not.

题意翻译

题目描述

Little Leticija正在准备编程考试。虽然她已经解决了很多任务,但还有一个任务尚未解决,所以她正在向你寻求帮助。您将获得单词S和Q查询。在每个查询中,给出正整数A,B,C和D.假设单词X由单词S中位置A和B之间的字母组成,而单词S中位置C和D之间的字母组成单词Y.如果可以以某种方式重新排列单词Y中的字母并获得单词X,则必须回答。

输入输出格式

** 输入格式:** 第一行输入包含单词S(1≤| S |≤50000)。| S | 表示单词S中的字符数,由英文字母的小写字母组成。第二行输入包含正整数Q(1≤Q≤50000)。 以下Q行中的每一行包含来自任务的四个整数A,B,C i D(1≤A≤B≤| S |且1≤C≤D≤| S |)。 ** 输出格式:** 对于每个查询,如果可能,输出“DA”(克罗地亚语为yes),如果不可能,则输出“NE”(克罗地亚语为否)。

输入输出样例

**输入样例#1: **

kileanimal
2
2 2 7 7
1 4 6 7

**输出样例#1: **

DA
NE

输入样例#2:

abababba
2
3 5 1 3
1 2 7 8

**输出样例#2: **

DA
DA

输入样例#3:

vodevovode
2
5 8 3 6
2 5 3 6

**输出样例#3: **

NE
DA

说明

在总分为50%的测试用例中,它将保持:1≤| S | ≤1000且1≤Q≤1000。 澄清第三个测试用例: 在第一个查询中,X =“vovo”,Y =“devo”。在第二个查询中,X =“odev”,Y =“devo”。

输入输出样例

输入 #1
kileanimal
2
2 2 7 7
1 4 6 7
输出 #1
DA
NE
输入 #2
abababba
2
3 5 1 3
1 2 7 8
输出 #2
DA
DA
输入 #3
vodevovode
2
5 8 3 6
2 5 3 6
输出 #3
NE
DA

说明/提示

In test cases worth 50% of total points, it will hold: 1 ≤ |S| ≤ 1000 and 1 ≤ Q ≤ 1000.

Clarification​ ​of​ ​the​ ​third​ ​test​ ​case:

In the first query, X=”vovo”, and Y=”devo”. In the second query, X=”odev”, and Y=”devo”.

思路

重新排列后要使两个字符串相等,我们只要让他们的a到z中的各个字母的个数相同就可以。

前缀和a[i][j](j<=26)表示从1到i,字母j出现的次数。每次循环iii位置上的字母+1,其他的字母不变。

利用容斥原理我们可以推出s(l,r)=sum[r]−sum[l−1]其中s(l,r)为l到r数字总和,sum[i]为1−i的总和。

代码

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

const int N=50010,M=30;

char c[N];
int q,a,b,cc,d;
int f[N][M];

int main() {
	cin>>c;
	int len=strlen(c);
	for(int i=1; i<=len; i++) {
		for(int j=1; j<=26; j++)
			f[i][j]=f[i-1][j];
		f[i][c[i-1]-'a'+1]++;
	}
	scanf("%d",&q);
	while(q--) {
		bool flag=false;
		scanf("%d%d%d%d",&a,&b,&cc,&d);
		for(int i=1; i<=26; i++)
			if(f[b][i]-f[a-1][i]!=f[d][i]-f[cc-1][i]) {
				flag=true;
				break;
			}
		if(flag)
			printf("NE\n");
		else
			printf("DA\n");
	}
	return 0;
}

 

猜你喜欢

转载自www.cnblogs.com/mysh/p/11831984.html