Advertisement
shamiul93

LightOJ - 1135 - Count the Multiples of 3

Apr 28th, 2017
175
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.89 KB | None | 0 0
  1. /**
  2. @author - Rumman BUET CSE'15
  3.  
  4. Problem - 1135 - Count the Multiples of 3
  5.  
  6. SPOJ MULTQ3 এর টুইন ব্রাদার ।
  7.  
  8. Concept - Segment Tree , Lazy Propagation
  9.  
  10. ** It is a beautiful problem on segment tree.
  11.  
  12. *** মেমরি লেন বানাচ্ছি । আজ থেকে ৫ বছর পর কই যাই জানি না । হয়তো এই স্মৃতি গুলো কেউ একদিন দেখবে ।
  13. হয়তো আমিই দেখবো । আর বাংলায় ঘটনা গুলো পড়ে অনেকেরই সুবিধা হবে এজন্য বাংলায় দেয়া  । :p
  14.  
  15. ** বাংলায় কই , নাইলে মজা নাই । :/
  16. ** এই প্রব্লেম করতে গিয়া বেশ টাইম গেসে । না । লজিক বাইর করতে যায় নাই । ইমপ্লিমেন্টে বাগ ধরতে গিয়া গেসে ।
  17. ** এই প্রব্লেম আমার জন্য স্পেশাল । কারণ , এই প্রব্লেমের লজিক পুরাটা আমার ডেভেলপ করা আর এর আইডিয়া ধরতে আমার টাইম লাগসে মাত্র ২ মিনিট । :3
  18. ** এবং এই আইডীয়া কোথাও থেকে শেখা না । অন্য সল্ভ দেখলে বুঝবা এই আইডিয়া অন্য কেউ ইউজ করে নাই । এটলিস্ট আমি দেখি নাই ।
  19. ** ইমপ্লিমেন্টে ভুল ধরতে ৫-৬ ঘণ্টা গেসে । -_-
  20.  
  21. আইডীয়াঃ
  22.  
  23.  
  24. একটা class থাকবে । zero , one , two . মানে
  25.  
  26. আমার আন্ডারের রেঞ্জের সবার সাথে ১ যোগ করলে যার ৩ দ্বারা ভাগশেষ ০ ছিলো তাঁর এখন ভাগশেষ হবে ১ , যার ১ ছিলো সে হবে ২ , আর ২ হবে ০
  27. সেই ভাবে সোয়াপ করার একটা সিস্টেম বাইর করসি । নিজেই ভেবে দেখো বুঝবা । :3
  28.  
  29.  
  30.  
  31. ভুলঃ
  32.  
  33.     seg[sp].zero = seg[2*sp+1].zero + seg[2*sp+2].zero ;
  34.     seg[sp].one = seg[2*sp+1].one + seg[2*sp+2].one ;
  35.     seg[sp].two = seg[2*sp+1].two + seg[2*sp+2].two ;
  36.  
  37.     seg[sp] = loopPropagate(seg[sp], seg[sp].prop % 3) ; /// এই লাইন টা লিখি নাই প্রথমে বাকী কোড ঠিক ছিলো । :/ তাহসিন ভাই ধরসে এইখানে ঘাপলা । :3
  38.  
  39.  
  40.     শিক্ষাঃ
  41.  
  42.     ১ । আপডেটে সবসময় মনে রাখবি  - যদি পুরা রেঞ্জ আমি কভার করি মানে   if(lo >= i && hi <= j) হয় , তাইলেই শুধুমাত্র prop এর ভ্যালু চেঞ্জ হবে ।
  43.     আর নাইলে prop কখনো নরমালি চেঞ্জ হবে না । তাইলে কি চেঞ্জ হবে ? হ্যাঁ । সাম বা অন্য ডাটা । কেমনে চেঞ্জ হবে ? আমার চাইল্ডের সব গুলা যেম্নে দরকার আমি মারজ করলাম ।
  44.  
  45.     ২ । এরপর ওই মারজড রেজাল্টের মধ্যে আমার নিজের prop এর প্রভাব এপ্লাই করতে হবে । হইতে পারে আগের মতো ( hi - lo + 1) * seg[sp].prop যোগ করতে হবে ।
  46.  
  47.      ৩ । এখানে যেটা করসি সেটা হলো ,     seg[sp].prop এর সমান সংখ্যক বার সোয়াপ করসি ।  loopPropagate ফাংশন ইউজ করে এই কাজ টা করসি ।
  48.  
  49.      ৪ । প্রতি কেসের শেষে অ্যারে ক্লিয়ার করা সবসময় উচিত । :3
  50.  
  51.      স্পেশালঃ
  52.  
  53.      ফাংশনে যখন ইটারেট এর জন্য সংখ্যা পাস করসি , তখন % ৩ করে পাস করসি । এতে লাভ হইসে যে , হায়েস্ট ২ বার লুপ ঘুরবে । নাইলে ৫০০০০ বার ও ঘুরা লাগতে পারতো ।
  54.      এই জিনিসটা না করলে ১.১০০ সেকেন্ড আসে , করলে ০.৪০৮ সেকেন্ড আসে । :p
  55.  
  56.  
  57. */
  58.  
  59.  
  60. #include <bits/stdc++.h>
  61. #define ll                                      long long
  62. #define fi                                      freopen("in.txt", "r", stdin)
  63. #define fo                                      freopen("out.txt", "w", stdout)
  64. #define m0(a) memset(a , 0 , sizeof(a))
  65. #define m1(a) memset(a , -1 , sizeof(a))
  66.  
  67. #define mx 100009
  68. using namespace std;
  69.  
  70.  
  71. ll i, j, idx, N ;
  72.  
  73. class node
  74. {
  75. public:
  76.     ll zero,  one, two, prop ;
  77.     node()
  78.     {
  79.         one = two = zero =  prop =  0 ;
  80.  
  81.     }
  82. } seg[mx*4];
  83.  
  84.  
  85. node build(ll lo, ll hi, ll sp)
  86. {
  87.     if(lo == hi)
  88.     {
  89.         seg[sp].zero = seg[sp].zero + 1 ;
  90.         return seg[sp];
  91.     }
  92.     ll mid ;
  93.     mid = (lo + hi) / 2 ;
  94.  
  95.     node l, r ;
  96.     l = build(lo, mid, 2*sp+1) ;
  97.     r = build(mid+1, hi, 2*sp+2) ;
  98.  
  99.     seg[sp].zero = l.zero + r.zero ;
  100. //    seg[sp].one = l.one + r.one ;
  101. //    seg[sp].two = l.two + r.two ;
  102.     return seg[sp] ;
  103. }
  104.  
  105.  
  106. node propagate(node a, ll x)
  107. {
  108.     a.prop += x ;
  109.     swap(a.zero, a.one) ;
  110.     swap(a.zero, a.two) ;
  111.     return a ;
  112. }
  113.  
  114.  
  115. node loopPropagate(node a, ll x)
  116. {
  117.     for(ll m = 0 ; m < x ; m++)
  118.     {
  119.         swap(a.zero, a.one) ;
  120.         swap(a.zero, a.two) ;
  121.     }
  122.     return a ;
  123. }
  124.  
  125.  
  126. node update(ll lo, ll hi, ll sp, ll x)
  127. {
  128.     if(lo > j || hi < i)
  129.     {
  130.         node n ;
  131.         return n;
  132.     }
  133.     if(lo >= i && hi <= j)
  134.     {
  135.         seg[sp] = propagate(seg[sp], x) ;
  136.         return seg[sp] ;
  137.     }
  138.     ll mid ;
  139.     mid = (lo + hi) / 2 ;
  140.  
  141.     update(lo, mid, 2*sp+1, x) ;
  142.     update(mid+1, hi, 2*sp+2, x) ;
  143.  
  144.     seg[sp].zero = seg[2*sp+1].zero + seg[2*sp+2].zero ;
  145.     seg[sp].one = seg[2*sp+1].one + seg[2*sp+2].one ;
  146.     seg[sp].two = seg[2*sp+1].two + seg[2*sp+2].two ;
  147.  
  148.     seg[sp] = loopPropagate(seg[sp], seg[sp].prop % 3) ; /// এই লাইন টাই মিস করসিলাম ।
  149.  
  150.     return seg[sp] ;
  151. }
  152.  
  153.  
  154. ll query(ll lo, ll hi, ll sp, ll carry)
  155. {
  156.     if(lo > j || hi < i)
  157.     {
  158.         return 0 ;
  159.     }
  160.     if(lo >= i && hi <= j)
  161.     {
  162.         node n ;
  163.         n = loopPropagate(seg[sp], carry % 3) ;
  164.         return n.zero ;
  165.     }
  166.  
  167.     ll mid ;
  168.     mid = (lo + hi) / 2 ;
  169.  
  170.     ll l, r ;
  171.     l = query(lo, mid, 2*sp+1, carry + seg[sp].prop) ;
  172.     r = query(mid+1, hi, 2*sp+2, carry+seg[sp].prop) ;
  173.  
  174.     return (l+r) ;
  175. }
  176.  
  177. int main()
  178. {
  179. //    fi ;
  180. //    fo ;
  181.     ll T, t = 0 ;
  182.     scanf("%lld",&T);
  183.     while(T--)
  184.     {
  185.         for(int k = 0 ; k < mx*4 ; k++)
  186.         {
  187.             seg[k].zero = 0 ;
  188.             seg[k].one = 0  ;
  189.             seg[k].two = 0 ;
  190.             seg[k].prop = 0 ;
  191.         }
  192.         t++ ;
  193.         ll q ;
  194.         scanf("%lld %lld",&N, &q) ;
  195.         build(0, N-1, 0) ;
  196.         printf("Case %lld:\n",t);
  197.         while(q--)
  198.         {
  199.             ll c ;
  200.             scanf("%lld %lld %lld",&c, &i, &j) ;
  201.             if(c==0)
  202.             {
  203.                 update(0, N-1, 0, 1) ;
  204.             }
  205.             else
  206.             {
  207.                 ll ans ;
  208.                 ans = query(0, N-1, 0, 0) ;
  209.                 printf("%lld\n",ans);
  210.             }
  211.         }
  212.     }
  213.     return 0 ;
  214. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement