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 segtree{
struct node{
ll sm, lazy_assign;
node(){
sm = 0, lazy_assign = -1;
}
node(ll x){
sm = x, lazy_assign = -1;
}
node operator+(node a){
return node((sm+a.sm)%md);
}
void propagate(node a, ll sz){
if(a.lazy_assign == -1) return;
sm = (a.lazy_assign*sz)%md;
lazy_assign = a.lazy_assign;
}
};
int k;
vector<node> v;
segtree(){}
segtree(int n){
k = 1;
while(k < n) k*=2;
k*=2;
v.resize(k, node());
}
void assign(int l, int r, int nd, int a, int b, ll x){
if(a > r || b < l) return;
if(a >= l && b <= r){
v[nd].sm = ((b-a+1)*x)%md;
v[nd].lazy_assign = x;
return;
}
int md = (a+b)/2;
v[2*nd].propagate(v[nd], md-a+1);
v[2*nd+1].propagate(v[nd], b-md);
v[nd].lazy_assign = -1;
assign(l, r, 2*nd, a, md, x);
assign(l, r, 2*nd+1, md+1, b, x);
v[nd] = v[2*nd]+v[2*nd+1];
}
void assign(int l, int r, ll x){
assign(l, r, 1, 0, k/2-1, x%md);
}
ll sum(int l, int r, int nd, int a, int b){
if(a > r || b < l) return 0;
if(a >= l && b <= r) return v[nd].sm;
int md = (a+b)/2;
v[2*nd].propagate(v[nd], md-a+1);
v[2*nd+1].propagate(v[nd], b-md);
v[nd].lazy_assign = -1;
ll rt = sum(l, r, 2*nd, a, md) + sum(l, r, 2*nd+1, md+1, b);
rt%=::md;
v[nd] = v[2*nd]+v[2*nd+1];
return rt;
}
ll sum(int l, int r){
return sum(l, r, 1, 0, k/2-1);
}
};
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));
dp[n-1] = vector<ll>(26, 1);
segtree high[26], low[26];
fill(high, high+26, segtree(n));
fill(low, low+26, segtree(n));
vector<bool> marked(n, 0);
for(int i = 0; i < 26; i++) low[i].assign(n-1, n-1, i+1), high[i].assign(n-1, n-1, 26-i);
for(int i = n-2; i >= 0; i--){
for(int x: gr[i]){
for(int j = i; j <= x; j++) marked[j] = 1;
for(int j = 0; j < 26; j++) low[j].assign(i, x, 0);
}
for(int x: lr[i]){
for(int j = i; j <= x; j++) marked[j] = 1;
for(int j = 0; j < 26; j++) high[j].assign(i, x, 0);
}
int lm = -1;
for(int j = i+1; j < n; j++) if(!marked[j]){
lm = j;
break;
}
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]+=high[0].sum(lm, lm);
}
ll s = 0;
for(int j = 0; j < 26; j++) s+=dp[i][j], s%=md, low[j].assign(i, i, s);
s = 0;
for(int j = 25; j >= 0; j--) s+=dp[i][j], s%=md, high[j].assign(i, i, s);
}
ll ans = 0;
for(ll x: dp[0]) ans+=x, ans%=md;
cout << ans << "\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... |