hdu 6387 AraBellaC

Problem Description
Princess Arabella loves the letter C, which earned her the epithet ArraBellaC. She would like to endeavor to construct a periodic string with length n(n≤20000) to spare her tedious time. In every period of the string, the substring begins with dozens of As and ends with dozens of Cs, and dozens of Bs are inserted between them, and the number of A, B, C is a, b, c.(For example, if a=1, b=1, c=2 then one of the period of the string is ABCC, and the periodic string is ABCCABCC……).Note that in the last period of the string, the substring can be incomplete and the last few letters of the period can be cut down.

And now, Arabella has constructed a periodic string, she want to give you a question: if she tells you the character is Ci(Ci∈{A,B,C}) in the Xi(Xi≤10000) , then could you tell her the value of a,b,c? If there are multiple answers, please find the lexicographically smallest answer. If you can’t find a valid answer, please print NO

Input
The first line gives an integer T(1≤T≤40) , which indicates the number of cases in the input.
The first line of every case contains only one integer m(1≤m≤5000), which means the number of characters AraBella told you.
A number Xi(1≤Xi≤10000) and a letter Ci are given in the following m lines, which means the position Xi in the string with letter Ci.

Output
Print a,b,c in order. If there are multiple answers, please find the lexicographically smallest answer. If you can’t find a valid answer, please print NO.(It is gratuated that 0<a,b,c, and please forget my poor Yinglish)

Sample Input
2
3
1 A
2 B
3 C
4
1 A
2 C
3 B
4 C

Sample Output
1 1 1
NO

题意:设x代表至少有一个x字符,构造一个串s: abc,然后s一直重复,要求:题目给出的条件,即,第几位必须是什么字符,
做法:枚举串的长度,对于某一个长度l,把串切成多个长度为l的子串,按照题意这写子串必定是相同的,那么记录a出现最右边的位置qa,b出现最左边的位置qbl,b出现最右边的位置qbr,c出现最左边的位置,如果qbl>qa&&qbr < qc;则对于这个长长度有某个串s使条件成立,
实现:对于某一段出现最左边最右边,应为长度至多为10000,那么建立3个数组,某个区间最大最小值就是上面提到的位置了,用st表预处理,查询是o(1),查询次数是调和级数的复杂度为nlogn。

#include<bits/stdc++.h>
using namespace std;
const int N= 10005;
int lg[N];

struct node{
    int st[N][20];
    int n;
    bool tmp;
    void init(int nx,int *p,bool tp){
        n = nx;tmp = tp;
        for(int i = 1;i <= n;i ++){
            if(!p[i] && !tp){
                p[i] = 100001;
            }
            st[i][0] =p[i];
        }
        int lg2 = lg[n];
        for(int i= 1;i <= lg2;i ++){
            for(int j = 1;j <= n;j ++){
                if(j+(1<<i) <= n+1)
                    st[j][i] = get(st[j][i-1],st[j+(1<<i-1)][i-1]);
                else st[j][i] = st[j][i-1];
            }
        }
    }
    int get(int a,int b){
        if(tmp) return max(a,b);
        else return min(a,b);
    }
    int query(int l,int r){
        r = min(r,n);
        int lg2 = lg[r-l+1];
        return get(st[l][lg2],st[r+1-(1<<lg2)][lg2]);
    }
}a,bl,br,c;
vector<int> va,vb,vc;

void init(){
    int np = 2;
    lg[1] = 0;
    for(int i = 2;i < N;i ++){
        lg[i] = lg[i-1];
        if(i > np) lg[i]++,np*=2;
    }
}

int num[N];
int main(){
    init();
    int T;
    cin >> T;
    while(T--){
        int m;
        scanf("%d",&m);
        va.clear(),vb.clear(),vc.clear();
        for(int i = 1;i <= m;i ++){
            int x;
            char st[10];
            scanf("%d %s",&x,st);
            if(st[0] == 'A') va.push_back(x);
            else if(st[0] == 'B') vb.push_back(x);
            else vc.push_back(x);
        }
        memset(num,0,sizeof(num));
        for(int i = 0;i < va.size();i ++) num[va[i]] = va[i];
        a.init(10000,num,true);
        memset(num,0,sizeof(num));
        for(int i = 0;i < vb.size();i ++) num[vb[i]] = vb[i];
        br.init(10000,num,true);
        bl.init(10000,num,false);
        memset(num,0,sizeof(num));
        for(int i = 0;i < vc.size();i ++) num[vc[i]] = vc[i];
        c.init(10000,num,false);
        bool tmp = false;
        for(int i= 3;i <= 10000;i ++){
            int qa = 0,qbl = i+1,qbr = -1,qc = i+1;
            for(int j= 1;j <= 10000;j += i){
                qa = max(qa,a.query(j,j+i-1)-j+1);
                qbl = min(qbl,bl.query(j,j+i-1)-j+1);
                qbr = max(qbr,br.query(j,j+i-1)-j+1);
                qc = min(qc,c.query(j,j+i-1)-j+1);
            }
            if(qbl <= qa || qbr >= qc) continue;
            else{
                if(qbl > qbr){
                    qa = max(qa,1);
                    qc = i-1-qa;
                }
                else{
                    qa = max(qa,1);
                    qc = i-qbr;
                }
                if(qa+qc == i) continue;
                if(!qa || !qc) continue;
                printf("%d %d %d\n",qa,i-qa-qc,qc);
                tmp =true;
                break;
            }
        }
        if(tmp == false)puts("NO");
    }


    return 0;
}

猜你喜欢

转载自blog.csdn.net/zstu_zy/article/details/82937868
hdu