Submission #549740

#TimeUsernameProblemLanguageResultExecution timeMemory
549740Jarif_RahmanMisspelling (JOI22_misspelling)C++17
100 / 100
3401 ms622572 KiB
#include <bits/stdc++.h>
#define pb push_back
#define f first
#define sc second
using namespace std;
typedef long long int ll;
typedef string str;

const ll md = 1000000007;

struct BIT{
    int n;
    vector<ll> sm;
    BIT(){}
    BIT(int _n){
        n = _n;
        sm.resize(n);
    }
    void add(int in, ll x){
        x%=md;
        in++;
        while(in <= n) sm[in-1]+=x, sm[in-1]%=md, in+=in&-in;
    }
    ll sum(int in){
        in++;
        ll s = 0;
        while(in >= 1) s+=sm[in-1], s%=md, in-=in&-in;
        return s;
    }
    ll sum(int l, int r){
        return (sum(r)-(l == 0? 0:sum(l-1)))%md;
    }
};

int main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0);

    int n, m; cin >> n >> m;
    vector<vector<int>> gr(n), lr(n);
    for(int i = 0; i < m; i++){
        int a, b; cin >> a >> b; a--, b--;
        if(a < b) lr[a].pb(b);
        else gr[b].pb(a);
    }

    vector<vector<ll>> dp(n, vector<ll>(26, 0));
    vector<vector<ll>> DP1(n, vector<ll>(26, 0));
    vector<vector<ll>> DP2(n, vector<ll>(26, 0));
    dp[n-1] = vector<ll>(26, 1);
    for(int i = 0; i < 26; i++)  DP1[n-1][i] = 26-i, DP2[n-1][i] = i+1;

    BIT high[26], low[26];
    fill(high, high+26, BIT(n));
    fill(low, low+26, BIT(n));

    set<int> ss;
    ss.insert(n-1);
    set<int> s1, s2;

    for(int i = n-2; i >= 0; i--){
        for(int x: gr[i]){
            auto it = ss.lower_bound(i);
            while(it != ss.end() && *it <= x){
                s1.insert(*it);
                for(int j = 0; j < 26; j++) high[j].add(*it, DP1[*it][j]);
                it = ss.erase(it);
            }
            it = s2.lower_bound(i);
            while(it != s2.end() && *it <= x){
                for(int j = 0; j < 26; j++) low[j].add(*it, -DP2[*it][j]);
                it = s2.erase(it);
            }
        }
        for(int x: lr[i]){
            auto it = ss.lower_bound(i);
            while(it != ss.end() && *it <= x){
                s2.insert(*it);
                for(int j = 0; j < 26; j++) low[j].add(*it, DP2[*it][j]);
                it = ss.erase(it);
            }
            it = s1.lower_bound(i);
            while(it != s1.end() && *it <= x){
                for(int j = 0; j < 26; j++) high[j].add(*it, -DP1[*it][j]);
                it = s1.erase(it);
            }
        }

        int lm = -1;
        if(!ss.empty()) lm = *ss.begin();

        for(int j = 0; j < 26; j++){
            if(j != 0) dp[i][j]+=low[j-1].sum(i, lm==-1?n-1:lm-1),dp[i][j]%=md;
            if(j != 25) dp[i][j]+=high[j+1].sum(i, lm==-1?n-1:lm-1),dp[i][j]%=md;
            if(lm == -1) dp[i][j]++, dp[i][j]%=md;
            else dp[i][j]+=DP1[lm][0];
        }

        DP1[i] = dp[i];
        DP2[i] = dp[i];

        for(int j = 24; j >= 0; j--) DP1[i][j]+=DP1[i][j+1], DP1[i][j]%=md;
        for(int j = 1; j < 26; j++) DP2[i][j]+=DP2[i][j-1], DP2[i][j]%=md;

        ss.insert(i);
    }

    if(DP1[0][0] < 0) DP1[0][0]+=md;

    cout << DP1[0][0] << "\n";
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...