洛谷 P4440 [COCI2017-2018#3] Programiranje

PS:如果读过题了可以跳过题目描述直接到题解部分
提交链接:洛谷 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.

提示

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”.

题目描述

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

样例输入 #1

kileanimal
2
2 2 7 7
1 4 6 7

样例输出 #1

DA
NE

样例 #2

样例输入 #2

abababba
2
3 5 1 3
1 2 7 8

样例输出 #2

DA
DA

样例 #3

样例输入 #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”。

题解

就直接维护每个字母的前缀和,最后相减就好了。
维护前缀和和相减的过程可以直接重载运算符,用起来还是很方便的。

代码实现

100pts

//洛谷 P4440 [COCI2017-2018#3] Programiranje
#pragma GCC optimize(3)
#include
#include
#include
using namespace std;
char s[500010];
int q,a,b,c,d;
int l;

struct zm{
	int a[27];
	zm(){
		memset(a,0,sizeof(a));
	}
	zm operator +(const zm b)const{
		zm c;
		for(int i=0;i<=26;++i){
			c.a[i]=b.a[i]+a[i];
		}
		return c;
	}
	zm operator -(const zm b)const{
		zm c;
		for(int i=0;i<=26;++i){
			c.a[i]=a[i]-b.a[i];
		}
		return c;
	}
	bool operator >=(const int b)const{
		for(int i=0;i<=26;++i){
			if(a[i]<b){
				return 0;
			}
		}
		return 1;
	}
}x[500010];

int main(){
	register int i;
	scanf("%s",&s);
	l=strlen(s);
	for(i=1;i<=l;++i){
		x[i]=x[i]+x[i-1];
		++x[i].a[s[i-1]-'a'];
	}
	scanf("%d",&q);
	for(i=1;i<=q;++i){
		scanf("%d%d%d%d",&a,&b,&c,&d);
		if((x[b]-x[a-1]-x[d]+x[c-1])>=0){
			puts("DA");
		}
		else{
			puts("NE");
		}
	}
	return 0;
}

你可能感兴趣的:(算法基础,前缀和)