This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#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 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... |