Guest User

Adding polynomial to segment tree

a guest
May 25th, 2020
287
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.43 KB | None | 0 0
  1. //Utkarsh.25dec
  2. #include <bits/stdc++.h>
  3. #include <chrono>
  4. #include <random>
  5. #define ll long long int
  6. #define ull unsigned long long int
  7. #define pb push_back
  8. #define mp make_pair
  9. #define mod 1000000007
  10. #define rep(i,n) for(ll i=0;i<n;i++)
  11. #define loop(i,a,b) for(ll i=a;i<=b;i++)
  12. #define vi vector <int>
  13. #define vs vector <string>
  14. #define vc vector <char>
  15. #define vl vector <ll>
  16. #define all(c) (c).begin(),(c).end()
  17. #define max3(a,b,c) max(max(a,b),c)
  18. #define min3(a,b,c) min(min(a,b),c)
  19. #define deb(x) cerr<<#x<<' '<<'='<<' '<<x<<'\n'
  20. using namespace std;
  21. #include <ext/pb_ds/assoc_container.hpp>
  22. #include <ext/pb_ds/tree_policy.hpp>
  23. using namespace __gnu_pbds;
  24. #define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>
  25. // ordered_set s ; s.order_of_key(val)  no. of elements strictly less than val
  26. // s.find_by_order(i)  itertor to ith element (0 indexed)
  27. typedef vector<vector<ll>> matrix;
  28. ll power(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
  29. ll modInverse(ll a){return power(a,mod-2);}
  30. const int N=100023;
  31. bool vis[N];
  32. vector <int> adj[N];
  33. // This is code for adding polynomial to segment tree
  34. // zero refers to x^3 and three refers to const
  35. ll zero[N],one[N],two[N],three[N];
  36. ll lazy[4*N][4];
  37. ll mytree[4*N];
  38. tuple <ll,ll,ll,ll> get_coefficients(ll l,int sign)
  39. {
  40.     tuple <ll,ll,ll,ll> ans;
  41.     get<0>(ans)=1;
  42.     ll temp=(6-3*l)%mod;
  43.     temp=(temp+mod)%mod;
  44.     get<1>(ans)=temp;
  45.     temp=(2-l)*(3-l)+(1-l)*(3-l)+(1-l)*(2-l);
  46.     temp%=mod;
  47.     temp=(temp+mod)%mod;
  48.     get<2>(ans)=temp;
  49.     temp=(1-l)*(2-l)*(3-l);
  50.     temp%=mod;
  51.     temp=(temp+mod)%mod;
  52.     get<3>(ans)=temp;
  53.     get<0>(ans)=(get<0>(ans)*sign);
  54.     get<0>(ans)=(get<0>(ans)+mod)%mod;
  55.     get<1>(ans)=(get<1>(ans)*sign);
  56.     get<1>(ans)=(get<1>(ans)+mod)%mod;
  57.     get<2>(ans)=(get<2>(ans)*sign);
  58.     get<2>(ans)=(get<2>(ans)+mod)%mod;
  59.     get<3>(ans)=(get<3>(ans)*sign);
  60.     get<3>(ans)=(get<3>(ans)+mod)%mod;
  61.     return ans;
  62. }
  63. ll get_sum(tuple <ll,ll,ll,ll> coeff,ll l,ll r)
  64. {
  65.     ll a,b,c,d;
  66.     tie(a,b,c,d)=coeff;
  67.     ll ans=d*(three[r]-three[l-1])+c*(two[r]-two[l-1])+b*(one[r]-one[l-1])+a*(zero[r]-zero[l-1]);
  68.     ans%=mod;
  69.     ans+=mod;
  70.     ans%=mod;
  71.     return ans;
  72. }
  73. void push(int v,int tl,int tr)
  74. {
  75.     mytree[v]+=(get_sum({lazy[v][0],lazy[v][1],lazy[v][2],lazy[v][3]},tl,tr));
  76.     mytree[v]%=mod;  
  77.     for(int i=0;i<4;i++)
  78.     {
  79.         if(tl!=tr)
  80.         {
  81.             lazy[2*v][i]+=lazy[v][i];
  82.             lazy[2*v][i]%=mod;
  83.             lazy[2*v+1][i]+=lazy[v][i];
  84.             lazy[2*v+1][i]%=mod;
  85.         }
  86.         lazy[v][i]=0;
  87.     }
  88. }
  89. void update(int v,int tl,int tr,int l,int r,tuple <ll,ll,ll,ll> add)
  90. {
  91.     if(tl>tr)
  92.         return;
  93.     push(v,tl,tr);
  94.     if(tl>r || tr<l)
  95.         return;
  96.     if(tl>=l && tr<=r)
  97.     {
  98.         lazy[v][0]=get<0>(add);
  99.         lazy[v][1]=get<1>(add);
  100.         lazy[v][2]=get<2>(add);
  101.         lazy[v][3]=get<3>(add);
  102.         push(v,tl,tr);
  103.         return;
  104.     }
  105.     int mid=(tl+tr)/2;
  106.     update(2*v,tl,mid,l,r,add);
  107.     update(2*v+1,mid+1,tr,l,r,add);
  108.     mytree[v]=(mytree[2*v]+mytree[2*v+1])%mod;
  109. }
  110. ll query(int v,int tl,int tr,int l,int r)
  111. {
  112.     if(tl>tr)
  113.         return 0;
  114.     push(v,tl,tr);
  115.     if(tl>r || tr<l)
  116.         return 0;
  117.     if(tl>=l && tr<=r)
  118.     {
  119.         return mytree[v];
  120.     }
  121.     int mid=(tl+tr)/2;
  122.     return (query(2*v,tl,mid,l,r)+query(2*v+1,mid+1,tr,l,r))%mod;
  123. }
  124. void solve()
  125. {
  126.     ll n,q;
  127.     cin>>n>>q;
  128.     for(int i=1;i<=n;i++)
  129.     {
  130.         zero[i]=zero[i-1]+((ll)i*i*i);
  131.         one[i]=one[i-1]+((ll)i*i);
  132.         two[i]=two[i-1]+((ll)i);
  133.         three[i]=three[i-1]+1;
  134.         zero[i]%=mod;
  135.         one[i]%=mod;
  136.         two[i]%=mod;
  137.         three[i]%=mod;
  138.     }
  139.     for(int _=1;_<=q;_++)
  140.     {
  141.         int t,x,y;
  142.         cin>>t>>x>>y;
  143.         if(t==0)
  144.         {
  145.             cout<<query(1,1,n,x,y)<<'\n';
  146.         }
  147.         else
  148.         {
  149.             int sign=1;
  150.             if(t==2)
  151.                 sign=-1;
  152.             auto add=get_coefficients(x,sign);
  153.             update(1,1,n,x,y,add);
  154.         }
  155.     }
  156. }
  157. int main()
  158. {
  159.     ios_base::sync_with_stdio(false);
  160.     cin.tie(NULL);
  161.     int T=1;
  162.     //cin>>T;
  163.     int t=0;
  164.     while(t++<T)
  165.     {
  166.         //cout<<"Case #"<<t<<":"<<' ';
  167.         solve();
  168.         //cout<<'\n';
  169.     }
  170.     cerr << "Time : " << 1000 * ((double)clock()) / (double)CLOCKS_PER_SEC << "ms\n";
  171. }
Add Comment
Please, Sign In to add comment