Advertisement
BaoJIaoPisu

Untitled

Nov 16th, 2022
852
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.07 KB | None | 0 0
  1. #include<bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. using ll = long long;
  6. using ld = long double;
  7. using ull = unsigned long long;
  8.  
  9. using pii = pair<int, int>;
  10. using pll = pair<ll, ll>;
  11. using pld = pair<ld, ld>;
  12.  
  13. #define fi first
  14. #define se second
  15. #define left BAO
  16. #define right ANH
  17. #define pb push_back
  18. #define pf push_front
  19. #define mp make_pair
  20. #define ins insert
  21. #define btpc __builtin_popcount
  22. #define btclz __builtin_clz
  23.  
  24. #define sz(x) (int)(x.size());
  25. #define all(x) x.begin(), x.end()
  26. #define debug(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "
  27.  
  28. mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
  29.  
  30. int d4x[4] = {1, 0, -1, 0}; int d4y[4] = {0, 1, 0, -1};
  31. int d8x[8] = {0, 1, 1, 1, 0, -1, -1, -1};
  32. int d8y[8] = {1, 1, 0, -1, -1, -1, 0, 1};
  33.  
  34. template<class X, class Y>
  35.     bool minimize(X &x, const Y &y) {
  36.         if (x > y)
  37.         {
  38.             x = y;
  39.             return true;
  40.         }
  41.         return false;
  42.     }
  43. template<class X, class Y>
  44.     bool maximize(X &x, const Y &y) {
  45.         if (x < y)
  46.         {
  47.             x = y;
  48.             return true;
  49.         }
  50.         return false;
  51.     }
  52.  
  53. const int MOD = 1e9 + 7; //998244353
  54.  
  55. template<class X, class Y>
  56.     void add(X &x, const Y &y) {
  57.         x = (x + y);
  58.         if(x >= MOD) x -= MOD;
  59.     }
  60.  
  61. template<class X, class Y>
  62.     void sub(X &x, const Y &y) {
  63.         x = (x - y);
  64.         if(x < 0) x += MOD;
  65.     }
  66.  
  67. /* Author : Le Ngoc Bao Anh, 12A5, LQD High School for Gifted Student*/
  68.  
  69. const ll INF = 1e9;
  70. const int N = 2e6 + 10;
  71. const int K = 20;
  72.  
  73. template <typename T> T mod_inv_in_range(T a, T m) {
  74.     // assert(0 <= a && a < m);
  75.     T x = a, y = m;
  76.     T vx = 1, vy = 0;
  77.     while (x) {
  78.         T k = y / x;
  79.         y %= x;
  80.         vy -= k * vx;
  81.         std::swap(x, y);
  82.         std::swap(vx, vy);
  83.     }
  84.     assert(y == 1);
  85.     return vy < 0 ? m + vy : vy;
  86. }
  87.  
  88. template <typename T> T mod_inv(T a, T m) {
  89.     a %= m;
  90.     a = a < 0 ? a + m : a;
  91.     return mod_inv_in_range(a, m);
  92. }
  93.  
  94. template <int MOD_> struct modnum {
  95.     static constexpr int MOD = MOD_;
  96.     static_assert(MOD_ > 0, "MOD must be positive");
  97.  
  98.     using ll = long long;
  99.  
  100.     int v;
  101.  
  102. public:
  103.  
  104.     modnum() : v(0) {}
  105.     modnum(ll v_) : v(int(v_ % MOD)) { if (v < 0) v += MOD; }
  106.     explicit operator int() const { return v; }
  107.     friend std::ostream& operator << (std::ostream& out, const modnum& n) { return out << int(n); }
  108.     friend std::istream& operator >> (std::istream& in, modnum& n) { ll v_; in >> v_; n = modnum(v_); return in; }
  109.  
  110.     friend bool operator == (const modnum& a, const modnum& b) { return a.v == b.v; }
  111.     friend bool operator != (const modnum& a, const modnum& b) { return a.v != b.v; }
  112.  
  113.     modnum inv() const {
  114.         modnum res;
  115.         res.v = mod_inv_in_range(v, MOD);
  116.         return res;
  117.     }
  118.     friend modnum inv(const modnum& m) { return m.inv(); }
  119.     modnum neg() const {
  120.         modnum res;
  121.         res.v = v ? MOD-v : 0;
  122.         return res;
  123.     }
  124.     friend modnum neg(const modnum& m) { return m.neg(); }
  125.  
  126.     modnum operator- () const {
  127.         return neg();
  128.     }
  129.     modnum operator+ () const {
  130.         return modnum(*this);
  131.     }
  132.  
  133.     modnum& operator ++ () {
  134.         v ++;
  135.         if (v == MOD) v = 0;
  136.         return *this;
  137.     }
  138.     modnum& operator -- () {
  139.         if (v == 0) v = MOD;
  140.         v --;
  141.         return *this;
  142.     }
  143.     modnum& operator += (const modnum& o) {
  144.         v -= MOD-o.v;
  145.         v = (v < 0) ? v + MOD : v;
  146.         return *this;
  147.     }
  148.     modnum& operator -= (const modnum& o) {
  149.         v -= o.v;
  150.         v = (v < 0) ? v + MOD : v;
  151.         return *this;
  152.     }
  153.     modnum& operator *= (const modnum& o) {
  154.         v = int(ll(v) * ll(o.v) % MOD);
  155.         return *this;
  156.     }
  157.     modnum& operator /= (const modnum& o) {
  158.         return *this *= o.inv();
  159.     }
  160.  
  161.     friend modnum operator ++ (modnum& a, int) { modnum r = a; ++a; return r; }
  162.     friend modnum operator -- (modnum& a, int) { modnum r = a; --a; return r; }
  163.     friend modnum operator + (const modnum& a, const modnum& b) { return modnum(a) += b; }
  164.     friend modnum operator - (const modnum& a, const modnum& b) { return modnum(a) -= b; }
  165.     friend modnum operator * (const modnum& a, const modnum& b) { return modnum(a) *= b; }
  166.     friend modnum operator / (const modnum& a, const modnum& b) { return modnum(a) /= b; }
  167. };
  168. using num = modnum<MOD>;
  169.  
  170. num P[K + 5][K + 5];
  171. num C[K + 5];
  172. int degree = 0;
  173.  
  174. void Gauss(int n) {
  175.     for(int i = 0; i < n; i++) {
  176.         for(int j = i; j < n; j++) {
  177.             if(P[j][i] != 0) {
  178.                 for(int k = 0; k <= n; k++) {
  179.                     swap(P[j][k], P[i][k]);
  180.                 }
  181.                 break;
  182.             }
  183.         }
  184.  
  185.         if(P[i][i] == 0) continue;
  186.         for(int j = 0; j < n; j++) {
  187.             if(i == j) continue;
  188.             num coef = P[j][i] / P[i][i];
  189.             for(int k = 0; k <= n; k++) P[j][k] -= P[i][k] * coef;
  190.         }
  191.     }
  192.  
  193.     for(int i = 0; i < n; i++) C[i] = P[i][n] / P[i][i];
  194.     degree = n - 1;
  195. }
  196.  
  197. num calc(int x) {
  198.     num T = 1, ans = 0;
  199.     for(int i = 0; i <= degree; i++) {
  200.         ans += T * C[i]; T = T * x;
  201.     }
  202.  
  203.     return ans;
  204. }
  205.  
  206. struct SegmentTree {
  207.     int n;
  208.     struct NODE {
  209.         num sum, fs, p;
  210.         int val, lazy = 0;
  211.  
  212.         NODE() {
  213.             sum = fs = p = 0;
  214.             val = lazy;
  215.         }
  216.     };
  217.     vector<num> D;
  218.     vector<NODE> node;
  219.  
  220.     SegmentTree(vector<int> values = {}) {
  221.         n = values.size();
  222.         node.resize(4 * n + 7);
  223.         D.resize(n + 7);
  224.            
  225.         for(int i = 1; i <= n; i++) {
  226.             D[i] = calc(values[i - 1]);
  227.         }
  228.         for(int i = 1; i <= 4 * n; i++) node[i] = NODE();
  229.  
  230.         Build(1, n, 1);
  231.     }
  232. private:
  233.     NODE merge(const NODE &left, const NODE &right) {
  234.         NODE ans = NODE();
  235.         ans.val = min(left.val, right.val);
  236.         ans.fs = left.fs + right.fs;
  237.         ans.sum = left.sum + right.sum;
  238.         if(ans.val) {
  239.             if(left.val == right.val) ans.p = left.p + right.p;
  240.             else ans.p = (left.val < right.val ? left.p + right.sum : left.sum + right.p);
  241.         }
  242.         return ans;
  243.     }
  244.  
  245.     void Build(int l, int r, int id) {
  246.         if(l == r) {
  247.             node[id].fs = D[l] - D[l - 1];
  248.             return;
  249.         }
  250.  
  251.         int mid = (l + r) >> 1;
  252.         Build(l, mid, id << 1);
  253.         Build(mid + 1, r, id << 1 | 1);
  254.         node[id] = merge(node[id << 1], node[id << 1 | 1]);
  255.     }
  256.  
  257.     void Down(int id) {
  258.         int &x = node[id].lazy;
  259.         if(!x) return;
  260.  
  261.         for(int i = (id << 1); i <= (id << 1 | 1); i++) {
  262.             if(x > 0) {
  263.                 if(!node[i].val) node[i].p = node[i].sum;
  264.                 node[i].val += x;
  265.                 node[i].sum = node[i].fs;
  266.                 node[i].lazy += x;
  267.             } else {
  268.                 node[i].val += x;
  269.                 if(!node[i].val) node[i].sum = node[i].p;              
  270.                 node[i].lazy += x;
  271.             }
  272.         }
  273.  
  274.         x = 0;
  275.     }
  276.  
  277.     void Update(int l, int r, int lo, int hi, int val, int id) {
  278.         if(l > hi || r < lo) return;
  279.         if(lo <= l && r <= hi) {
  280.             if(val == 1) {
  281.                 node[id].val++;
  282.                 if(node[id].val == 1) node[id].p = node[id].sum;
  283.                 node[id].sum = node[id].fs;
  284.             } else {
  285.                 node[id].val--;
  286.                 if(!node[id].val) node[id].sum = node[id].p;
  287.             }
  288.             node[id].lazy += val;
  289.             return;
  290.         }
  291.  
  292.         Down(id);
  293.         int mid = (l + r) >> 1;
  294.         Update(l, mid, lo, hi, val, id << 1);
  295.         Update(mid + 1, r, lo, hi, val, id << 1 | 1);
  296.         node[id] = merge(node[id << 1], node[id << 1 | 1]);
  297.     }
  298. public:
  299.     void update(int l, int r, int val) {
  300.         Update(1, n, l, r, val, 1);
  301.     }
  302. };
  303.  
  304. struct Recs {
  305.     int x, y, u, v;
  306. } recs[N];
  307. vector<pii> events[N];
  308.  
  309. void BaoJiaoPisu() {
  310.     int n, k; cin >> n >> k;
  311.  
  312.     //find formula for 1 ^ k + 2 ^ k + ... + x ^ k
  313.     num S = 0;
  314.     for(int i = 0; i < k + 2; i++) {
  315.         num T = 1;
  316.         for(int j = 1; j <= k; j++) T *= (i + 1);
  317.         S += T;
  318.  
  319.         T = 1;
  320.         for(int j = 0; j <= k + 1; j++) {
  321.             P[i][j] = T; T = T * (i + 1);
  322.         }
  323.         P[i][k + 2] = S;
  324.     }  
  325.     Gauss(k + 2);
  326.  
  327.     //Sweepline to calculate answer
  328.     vector<int> values;
  329.     for(int i = 1; i <= n; i++) {
  330.         cin >> recs[i].x >> recs[i].y >> recs[i].u >> recs[i].v;
  331.         values.pb(recs[i].x);
  332.         values.pb(recs[i].y);
  333.         values.pb(recs[i].u);
  334.         values.pb(recs[i].v);
  335.         values.pb(recs[i].v + 1);
  336.         values.pb(recs[i].x - 1);
  337.         values.pb(recs[i].u - 1);
  338.     }
  339.  
  340.     sort(all(values)); values.resize(unique(all(values)) - values.begin());
  341.  
  342.     SegmentTree IT = SegmentTree(values);
  343.     for(int i = 1; i <= n; i++) {
  344.         recs[i].x = lower_bound(all(values), recs[i].x) - values.begin() + 1;
  345.         recs[i].y = lower_bound(all(values), recs[i].y) - values.begin() + 1;
  346.         recs[i].u = lower_bound(all(values), recs[i].u) - values.begin() + 1;
  347.         recs[i].v = lower_bound(all(values), recs[i].v) - values.begin() + 1;
  348.         events[recs[i].y].pb(mp(recs[i].x, recs[i].u));
  349.         events[recs[i].v + 1].pb(mp(-recs[i].x, recs[i].u));
  350.     }
  351.  
  352.     num ans = 0;
  353.     int last = 1;
  354.     for(int i = 1; i <= values.size(); i++) {
  355.         if(i > 1) {
  356.             ans += IT.node[1].sum * (calc(values[i - 1] - 1) - calc(last - 1));
  357.         }
  358.         last = values[i - 1];
  359.         for(pii e : events[i]) {
  360.             IT.update(abs(e.fi), e.se, (e.fi < 0 ? -1 : 1));
  361.         }
  362.     }
  363.  
  364.     cout << ans;
  365. }
  366.  
  367. int main()
  368. {
  369.     ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
  370.     #ifndef ONLINE_JUDGE
  371.     freopen("input.txt", "r", stdin);
  372.     freopen("output.txt", "w", stdout);
  373.     #else
  374.     //online
  375.     #endif
  376.  
  377.     int tc = 1, ddd = 0;
  378.     // cin >> tc;
  379.     while(tc--) {
  380.         //ddd++;
  381.         //cout << "Case #" << ddd << ": ";
  382.         BaoJiaoPisu();
  383.     }
  384. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement