#pragma GCC optimize("O2,unroll-loops")
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
const int treeSize = (1<<18); //Power of 2
//Root at 1
int segTree[treeSize][26] = {0};
int padding = (treeSize/2);
//Adds amount to the letter index from the index (included) to the end
void addLetterFromIndex(int letter, int amount, int index, int currNode, int NodeRangeLeft, int NodeRangeRight){
    if (index<=NodeRangeLeft){
        // printf("Added %d to tree index %d (range %d-%d)\n",amount,currNode, NodeRangeLeft, NodeRangeRight);
        segTree[currNode][letter]+=amount;
        return;
    }
    if (NodeRangeRight<index){
        return;
    }
    else{
        int middle = NodeRangeLeft+((NodeRangeRight-NodeRangeLeft)/2);
        addLetterFromIndex(letter, amount, index, currNode*2, NodeRangeLeft, middle);
        addLetterFromIndex(letter, amount, index, currNode*2+1, middle+1, NodeRangeRight);
    }
}
//Index must be 0-indexed and from original array
int letterAtIndex(int index, int letterIdx){
    int letterAmount = 0;
    int visiting = index+padding;
    bool visited1 = false;
    while (!visited1){
        letterAmount += segTree[visiting][letterIdx];
        if (visiting==1){
            visited1 = true;
        }
        visiting/=2;
    }
    return letterAmount;
}
//Returns last wrong letter (if 26 then word is correct)
int checkInterval(int left, int right, int lastWrong, int maxLetterIdx){
    for (int i = lastWrong;i<maxLetterIdx+1;++i){
        int leftLetterCount = 0;
        if (left!=0){
            leftLetterCount = letterAtIndex(left-1,i);
        }
        int rightLetterCount = letterAtIndex(right,i);
        if (abs(leftLetterCount-rightLetterCount)>1){
            return i;
            break;
        }
    }
    // printf("Interval %d-%d is correct\n",left,right);
    return 26;
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    string word;
    getline(cin,word);
    int nbIntervals;
    cin >> nbIntervals;
    int lowestSeenLetter = 25;
    int highestSeenLetter = 0;
    //Intervals are inclusive on both sides (but 1-indexed)
    vector<pair<int,int> > intervals;
    int longestInterval = 0;
    for (int i = 0; i<nbIntervals;++i){
        int start,end;
        cin >> start >> end;
        //Add them 0-indexed
        intervals.push_back({start-1,end-1});
        longestInterval = max(longestInterval,end-start+1);
    }
    // printf("Got intervals\n");
    vector<int> snowballOrder;
    for (int i = 0;i<word.size();++i){
        int target;
        cin >> target;
        snowballOrder.push_back(target);
    }
    // printf("Got snowballOrder\n");
    for (int i = 0;i<word.size();++i){
        char c = word[i];
        lowestSeenLetter = min(lowestSeenLetter,c-'a');
        highestSeenLetter = max(highestSeenLetter,c-'a');
        // printf("Adding %c to tree\n",c);
        addLetterFromIndex(c-'a',1,i,1,0,padding-1);
    }
    int minSnowBallsForCorrect = longestInterval-26;
    bool totalWordIsGood = false;
    int firstUnvalidIntervalIdx = 0;
    int firstUnvalidLetterIdx = lowestSeenLetter;
    if (minSnowBallsForCorrect<0){
        bool allIntervals = true;
        for (int i = firstUnvalidIntervalIdx; i<nbIntervals; ++i){
            pair<int,int> interval = intervals[i];
            int currFirstUnvalidLetter = checkInterval(interval.first, interval.second, firstUnvalidLetterIdx, highestSeenLetter);
            if (currFirstUnvalidLetter != 26){
                allIntervals = false;
                firstUnvalidIntervalIdx = i;
                firstUnvalidLetterIdx = currFirstUnvalidLetter;
                break;
            }
            else{
                // printf("Interval %d-%d is valid\n",interval.first,interval.second);
            }
        }
        if (allIntervals){
            printf("0\n");
            return 0;
        }
    }
    for (int SnowballIdx = 0;SnowballIdx<word.size();++SnowballIdx){
        // printf("Snowball %d : \n",SnowballIdx+1);
        int idx = snowballOrder[SnowballIdx];
        char letterHit = word[idx-1];
        addLetterFromIndex(letterHit-'a',-1,idx-1,1,0,padding-1);
        //Check that enough snow balls have hit and that the last snowball covered the blocking letter
        if (minSnowBallsForCorrect<=SnowballIdx+1){ //(letterHit-'a' == firstUnvalidLetterIdx) && 
            bool remainingIntervals = true;
            for (int i = firstUnvalidIntervalIdx; i<nbIntervals; ++i){
                pair<int,int> interval = intervals[i];
                int remainingIntervalsFirstUnvalidLetter = checkInterval(interval.first, interval.second, firstUnvalidLetterIdx, highestSeenLetter);
                if (remainingIntervalsFirstUnvalidLetter != 26){
                    remainingIntervals = false;
                    firstUnvalidIntervalIdx = i;
                    firstUnvalidLetterIdx = remainingIntervalsFirstUnvalidLetter;
                    break;
                }
                else{
                    // printf("Interval %d-%d is valid\n",interval.first,interval.second);
                    //Word is right so firstUnvalidLetterIdx is 0
                    firstUnvalidLetterIdx = lowestSeenLetter;
                }
            }
            if (remainingIntervals){
                printf("%d\n",SnowballIdx+1);
                return 0;
            }
        }
    }
    printf("Impossible\n");
}
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... |