mihaimarcel21

numbers_tree

Jan 12th, 2021 (edited)
700
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.98 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int N=100005, MAXNR=1000005;
  4. struct Node
  5. {
  6.     int st=0,dr=0,Query3=0,Query2=0;
  7. };
  8. Node Tree[4*N], zero;
  9. int lazy[4*N];
  10. int n,val,ql,qr;
  11. bitset<MAXNR>isPrime;
  12.  
  13. inline void updateLazy(int tl,int tr,int ti)
  14. {
  15.     if(isPrime[lazy[ti]])
  16.     {
  17.         Tree[ti].st=tr-tl+1;
  18.         Tree[ti].dr=tr-tl+1;
  19.         Tree[ti].Query3=tr-tl+1;
  20.         Tree[ti].Query2=0;
  21.     }
  22.     else
  23.     {
  24.         Tree[ti].st=0;
  25.         Tree[ti].dr=0;
  26.         Tree[ti].Query3=0;
  27.         Tree[ti].Query2=tr-tl+1;
  28.     }
  29.     if(tl<tr)
  30.     {
  31.         lazy[ti*2]=lazy[ti];
  32.         lazy[ti*2+1]=lazy[ti];
  33.     }
  34.     lazy[ti]=0;
  35. }
  36.  
  37. void updateRange(int tl=1,int tr=n,int ti=1)
  38. {
  39.     if(lazy[ti])
  40.         updateLazy(tl,tr,ti);
  41.     if(tr<ql||qr<tl)
  42.         return;
  43.     if(ql<=tl&&tr<=qr)
  44.     {
  45.         lazy[ti]=val;
  46.         updateLazy(tl,tr,ti);
  47.         return;
  48.     }
  49.  
  50.     int mid=(tl+tr)/2;
  51.     updateRange(tl,mid,ti*2);
  52.     updateRange(mid+1,tr,ti*2+1);
  53.     Tree[ti].st=max(Tree[ti*2].st,(Tree[ti*2].Query2==0) ? Tree[ti*2].st+Tree[ti*2+1].st : 0);
  54.     Tree[ti].dr=max(Tree[ti*2+1].dr,(Tree[ti*2+1].Query2==0) ? Tree[ti*2+1].dr+Tree[ti*2].dr : 0);
  55.     Tree[ti].Query3=max(max(Tree[ti*2].Query3,Tree[ti*2+1].Query3),Tree[ti*2].dr+Tree[ti*2+1].st);
  56.     Tree[ti].Query2=Tree[ti*2].Query2+Tree[ti*2+1].Query2;
  57. }
  58.  
  59. int queryRange(int tl=1,int tr=n,int ti=1)
  60. {
  61.     if(lazy[ti])
  62.         updateLazy(tl,tr,ti);
  63.     if(tr<ql||qr<tl)
  64.         return 0;
  65.     if(ql<=tl&&tr<=qr)
  66.         return Tree[ti].Query2;
  67.     int mid=(tl+tr)/2;
  68.     return queryRange(tl,mid,ti*2)+queryRange(mid+1,tr,ti*2+1);
  69. }
  70.  
  71. Node queryRange3(int tl=1,int tr=n,int ti=1)
  72. {
  73.     if(lazy[ti])
  74.         updateLazy(tl,tr,ti);
  75.     if(tr<ql || qr<tl)
  76.         return zero;
  77.     if(ql<=tl && tr<=qr)
  78.         return Tree[ti];
  79.     int mid=(tl+tr)/2;
  80.     Node left=queryRange3(tl,mid,ti*2);
  81.     Node right=queryRange3(mid+1,tr,ti*2+1);
  82.     Node ans;
  83.     ans.st=max(left.st,(left.Query2==0)?left.st+right.st:0);
  84.     ans.dr=max(right.dr,(right.Query2==0)?right.dr+left.dr:0);
  85.     ans.Query3=max(max(left.Query3,right.Query3),left.dr+right.st);
  86.     ans.Query2=left.Query2+right.Query2;
  87.     return ans;
  88. }
  89.  
  90. void sieveOfEratosthenes()
  91. {
  92.     isPrime.set();
  93.     int pi;
  94.     for(int i=2;i*i<MAXNR;++i)
  95.         if(isPrime[i])
  96.             for( pi=i*2; pi<MAXNR; pi+=i)
  97.                 isPrime[pi]=false;
  98. }
  99. int main()
  100. {
  101.     ios::sync_with_stdio(false);
  102.     sieveOfEratosthenes();
  103.     int op,q;
  104.     ifstream fin("numbers_tree.in");
  105.     fin>>n>>q;
  106.     for(int i=1;i<=n;++i)
  107.     {
  108.         fin>>val;
  109.         ql=qr=i;
  110.         updateRange();
  111.     }
  112.     ofstream fout("numbers_tree.out");
  113.     while(q--)
  114.     {
  115.         fin>>op>>ql>>qr;
  116.         if(op==1)
  117.         {
  118.             fin>>val;
  119.             updateRange();
  120.         }
  121.         else
  122.             if(op==2)
  123.                 fout<<queryRange()<<'\n';
  124.             else
  125.                 fout<<queryRange3().Query3<<'\n';
  126.     }
  127.     return 0;
  128. }
  129.  
Add Comment
Please, Sign In to add comment