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”(克罗地亚语为否)。
kileanimal
2
2 2 7 7
1 4 6 7
DA
NE
abababba
2
3 5 1 3
1 2 7 8
DA
DA
vodevovode
2
5 8 3 6
2 5 3 6
NE
DA
在总分为50%的测试用例中,它将保持:1≤| S | ≤1000且1≤Q≤1000。
澄清第三个测试用例:
在第一个查询中,X =“vovo”,Y =“devo”。在第二个查询中,X =“odev”,Y =“devo”。
就直接维护每个字母的前缀和,最后相减就好了。
维护前缀和和相减的过程可以直接重载运算符,用起来还是很方便的。
//洛谷 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;
}