niyaznigmatullin

Untitled

May 6th, 2015
307
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 12.80 KB | None | 0 0
  1. import java.io.*;
  2. import java.math.BigInteger;
  3. import java.util.*;
  4.  
  5. public class Day2I {
  6.     FastScanner in;
  7.     PrintWriter out;
  8.  
  9.     final long md = 1000000007;
  10.  
  11.     long add(long a, long b, long c) {
  12.         long res = (a % c + b % c) % c;
  13.         if (res < 0)
  14.             res += c;
  15.         return res;
  16.     }
  17.  
  18.     long sub(long a, long b, long c) {
  19.         long res = (a % c - b % c) % c;
  20.         if (res < 0)
  21.             res += c;
  22.         return res;
  23.     }
  24.  
  25.     long mul(long a, long b, long c) {
  26.         a %= c;
  27.         b %= c;
  28.         if (a < 0)
  29.             a += c;
  30.         if (b < 0)
  31.             b += c;
  32.         long res = 0;
  33.         while (b > 0) {
  34.             if ((b & 1) == 1) {
  35.                 res = add(res, a, c);
  36.             }
  37.             a = add(a, a, c);
  38.             b >>= 1;
  39.         }
  40.         return res % c;
  41.     }
  42.  
  43.     long power(long a, long b, long c) {
  44.         long res = 1;
  45.         while (b > 0) {
  46.             if ((b & 1) != 0) {
  47.                 res = mul(res, a, c);
  48.             }
  49.             a = mul(a, a, c);
  50.             b >>= 1;
  51.         }
  52.         return res % c;
  53.     }
  54.  
  55.     long inverse(long a, long p) {
  56.         return power(a, p - 2, p);
  57.     }
  58.  
  59.     long get_sum(long a, long cnt, long p) {
  60.         if (cnt == 0) {
  61.             return 0;
  62.         }
  63.         if (cnt == 1) {
  64.             return 1;
  65.         }
  66.         long u = get_sum(a, cnt / 2, p);
  67.         u = mul(u, power(a, cnt / 2, p) + 1, p);
  68.         if (cnt % 2 == 1) {
  69.             u = add(mul(u, a, p), 1, p);
  70.         }
  71.         return u;
  72.     }
  73.  
  74.     long divide_power(long a, long b, long p, long md) {
  75.         if (p != md) {
  76.             long rem = power(a, b, p);
  77.             long value = sub(power(a, b, md), rem, md);
  78.             value = mul(value, inverse(p, md), md);
  79.             return value;
  80.         }
  81.         return power(a, b, md * md) / md;
  82.     }
  83.  
  84.     long divide_product(long a, long b, long p, long md) {
  85.         if (p != md) {
  86.             long rem = mul(a, b, p);
  87.             long value = sub(mul(a, b, md), rem, md);
  88.             value = mul(value, inverse(p, md), md);
  89.             return value;
  90.         }
  91.         return mul(a, b, md * md) / md;
  92.     }
  93.  
  94.     long divide_sum_and_product(long x, long a, long b, long p, long md) {
  95.         if (p != md) {
  96.             long rem = add(x, mul(a, b, p), p);
  97.             long value = sub(add(x, mul(a, b, md), md), rem, md);
  98.             value = mul(value, inverse(p, md), md);
  99.             return value;
  100.         }
  101.         return add(x, mul(a, b, md * md), md * md) / md;
  102.     }
  103.  
  104.     long such_solve(long x, long p, long step, long r1, long r2) {
  105.         if (r1 == 0 || r2 == 0) {
  106.             return 0;
  107.         }
  108.         if (step == 0) {
  109.             return (x < r2 ? r1 : 0);
  110.         }
  111.         long ans = 0;
  112.         long t = Math.min(r1 - 1, (p - x - 1) / step);
  113.         if (x < r2) {
  114.             ans = add(Math.min(t, (r2 - x - 1) / step), 1, md);
  115.         }
  116.         x = add(x, mul(t + 1, step, p), p);
  117.         r1 -= (t + 1);
  118.         if (r1 == 0) {
  119.             return ans;
  120.         }
  121.         long last = add(x, mul(r1 - 1, step, p), p);
  122.         long after = last / step + 1;
  123.         ans = add(ans, after, md);
  124.         if (last >= r2) {
  125.             ans = sub(ans, (last - r2) / step + 1, md);
  126.         }
  127.         r1 -= after;
  128.         if (r1 == 0) {
  129.             return ans;
  130.         }
  131.         long rounds = BigInteger.valueOf(x).add(BigInteger.valueOf(r1).multiply(BigInteger.valueOf(step))).divide(BigInteger.valueOf(p)).longValue();
  132.         long small = such_solve(x, step, sub(step, p % step, step), rounds, r2
  133.                 % step);
  134.         ans = add(ans, mul(small, r2 / step + 1, md), md);
  135.         ans = add(ans, mul(rounds - small, r2 / step, md), md);
  136.         return ans;
  137.     }
  138.  
  139.     long solve_real_problem(long c1, long c2, long x, long p, long r1, long r2) {
  140.         long c2inv = inverse(c2, p);
  141.         c1 = mul(c1, c2inv, p);
  142.         x = mul(x, c2inv, p);
  143.         long step = sub(p, c1, p);
  144.         long res = such_solve(x, p, step, r1, r2);
  145.         return res;
  146.     }
  147.  
  148.     long mySolve(long p, long x, long _L, long _R, long k) {
  149.         long len = _R - _L + 1;
  150.         long c1 = get_sum(power(2, k, p), len / k + 1, p);
  151.         long c2 = mul(get_sum(power(2, k, p), len / k, p),
  152.                 power(2, len % k, p), p);
  153.         if (c1 == 0 && c2 == 0) {
  154.             long ans = 0;
  155.             if (x == 0) {
  156.                 ans = power(2, k, md);
  157.             }
  158.             return ans;
  159.         }
  160.         if (c1 == 0) {
  161.             long bmod = mul(x, inverse(c2, p), p);
  162.             long bcnt = divide_power(2, k - len % k, p, md);
  163.             long rem = power(2, k - len % k, p);
  164.             if (bmod < rem) {
  165.                 bcnt++;
  166.             }
  167.             long ans = mul(power(2, len % k, md), bcnt, md);
  168.             return ans;
  169.         }
  170.         if (c2 == 0) {
  171.             long amod = mul(x, inverse(c1, p), p);
  172.             long acnt = divide_power(2, len % k, p, md);
  173.             long rem = power(2, len % k, p);
  174.             if (amod < rem) {
  175.                 acnt++;
  176.             }
  177.             long ans = mul(acnt, power(2, k - len % k, md), md);
  178.             return ans;
  179.         }
  180.         long r1 = power(2, len % k, p);
  181.         long r2 = power(2, k - len % k, p);
  182.         long ans = divide_power(2, k, p, md);
  183.         ans = sub(ans, divide_product(r1, r2, p, md), md);
  184.         ans = add(ans, solve_real_problem(c1, c2, x, p, r1, r2), md);
  185.         return ans;
  186.     }
  187.  
  188.     long stupid(long p, long x, long l, long r, long k) {
  189.         long res = 0;
  190.         for (int st = 0; st < 1 << k; st++) {
  191.             String t = "";
  192.             for (int i = 0; i < k; i++) {
  193.                 if (((1 << i) & st) != 0) {
  194.                     t = t + "1";
  195.                 } else {
  196.                     t = t + "0";
  197.                 }
  198.             }
  199.             String s = "";
  200.             while (s.length() <= r) {
  201.                 s += t;
  202.             }
  203.             s = s.substring((int) l, (int) r + 1);
  204.             long value = 0;
  205.             for (int i = 0; i < s.length(); i++) {
  206.                 value = value * 2 + (s.charAt(i) - '0');
  207.                 value %= p;
  208.             }
  209.             if (value == x) {
  210.                 res++;
  211.             }
  212.         }
  213.         return res;
  214.     }
  215.  
  216.     void solve5555() {
  217.         Random rnd = new Random(123);
  218.         for (int it = 0; it < 123123; it++) {
  219.             System.err.println("iter = " + it);
  220.             final int MAX = (int) 1e9;
  221.             long a = (long) (rnd.nextInt(MAX) * 1e9 + rnd.nextInt(MAX));
  222.             long b = (long) (rnd.nextInt(MAX) * 1e9 + rnd.nextInt(MAX));
  223.             long p = (long) (rnd.nextInt(MAX) * 1e9 + rnd.nextInt(MAX));
  224.             long x = (long) (rnd.nextInt(MAX) * 1e9 + rnd.nextInt(MAX));
  225.             p = BigInteger.valueOf(p).nextProbablePrime().longValue();
  226.             long res = divide_sum_and_product(x, a, b, p, md);
  227.             long correct = BigInteger.valueOf(a)
  228.                     .multiply(BigInteger.valueOf(b)).add(BigInteger.valueOf(x))
  229.                     .divide(BigInteger.valueOf(p)).mod(BigInteger.valueOf(md))
  230.                     .longValue();
  231.             if (res != correct) {
  232.                 System.err.println("res = " + res);
  233.                 System.err.println("correct = " + correct);
  234.                 throw new AssertionError();
  235.             }
  236.         }
  237.     }
  238.      
  239.     void solve333333() {
  240.         Random rnd = new Random(123);
  241.         for (int it = 0; it < 123123; it++) {
  242.             System.err.println("iter = " + it);
  243.             final int MAX = 100;
  244.             long a = 1 + rnd.nextInt(MAX);
  245.             long cnt = 1 + rnd.nextInt(MAX);
  246.             long p = (long) (rnd.nextInt(MAX) * 1e9 + rnd.nextInt(MAX));
  247.             p = BigInteger.valueOf(p).nextProbablePrime().longValue();
  248.             long res = get_sum(a, cnt, p);
  249.             BigInteger corr = BigInteger.ZERO;
  250.             BigInteger mul = BigInteger.ONE;
  251.             for (int i = 0; i < cnt; i++) {
  252.                 corr = corr.add(mul);
  253.                 mul = mul.multiply(BigInteger.valueOf(a));
  254.             }
  255.             long correct = corr.mod(BigInteger.valueOf(p)).longValue();
  256.             if (res != correct) {
  257.                 System.err.println("a = " + a + ", cnt = " + cnt + ", p = " + p);
  258.                 System.err.println("res = " + res);
  259.                 System.err.println("correct = " + correct);
  260.                 throw new AssertionError();
  261.             }
  262.         }
  263.     }
  264.  
  265.     void solve12322() {
  266.         Random rnd = new Random(123);
  267.         for (int it = 0; it < 123123; it++) {
  268.             System.err.println("iters = " + it);
  269.             final int MAX = (int) 1e9;
  270.             long a = (long) (rnd.nextInt(MAX) * 1e9 + rnd.nextInt(MAX));
  271.             long b = rnd.nextInt(1000) + 1;//(long) (rnd.nextInt(MAX) * 1e9 + rnd.nextInt(MAX));
  272.             long p = (long) (rnd.nextInt(MAX) * 1e9 + rnd.nextInt(MAX));
  273.             p = BigInteger.valueOf(p).nextProbablePrime().longValue();
  274.             long res = divide_power(a, b, p, md);
  275.             long correct = BigInteger
  276.                     .valueOf(a)
  277.                     .pow((int) b)
  278.                     .divide(BigInteger.valueOf(p)).mod(BigInteger.valueOf(md)).longValue();
  279.             if (res != correct) {
  280.                 System.err.println("res = " + res);
  281.                 System.err.println("correct = " + correct);
  282.                 throw new AssertionError();
  283.             }
  284.         }
  285.     }
  286.  
  287.     void solv3e123() {
  288.         Random rnd = new Random(123);
  289.         final int MAX = 14;
  290.         for (int it = 0; it < 123123; it++) {
  291.             System.err.println("iter = " + it);
  292.             int p = BigInteger.valueOf(3 + rnd.nextInt(MAX))
  293.                     .nextProbablePrime().intValue();
  294.             int x = rnd.nextInt(p);
  295.             int l = rnd.nextInt(MAX), r = rnd.nextInt(MAX);
  296.             if (r < l) {
  297.                 int tmp = l;
  298.                 l = r;
  299.                 r = tmp;
  300.             }
  301.             int k = 1 + rnd.nextInt(MAX);
  302.             long my = mySolve(p, x, l, r, k);
  303.             long stupid = stupid(p, x, l, r, k);
  304.             if (my != stupid) {
  305.                 System.err.println("my = " + my);
  306.                 System.err.println("correct = " + stupid);
  307.                 throw new AssertionError();
  308.             }
  309.         }
  310.     }
  311.  
  312.     void solve() {
  313.         while (true) {
  314.             long p = in.nextLong();
  315.             long x = in.nextLong();
  316.             long l = in.nextLong();
  317.             long r = in.nextLong();
  318.             long k = in.nextLong();
  319.             if (p == 0) {
  320.                 break;
  321.             }
  322.             out.println(mySolve(p, x, l, r, k));
  323.         }
  324.     }
  325.  
  326.     void run() {
  327.         try {
  328.             in = new FastScanner(new File("object.in"));
  329.             out = new PrintWriter(new File("object.out"));
  330.  
  331.             solve();
  332.  
  333.             out.close();
  334.         } catch (FileNotFoundException e) {
  335.             e.printStackTrace();
  336.         }
  337.     }
  338.  
  339.     void runIO() {
  340.  
  341.         in = new FastScanner(System.in);
  342.         out = new PrintWriter(System.out);
  343.  
  344.         solve();
  345.  
  346.         out.close();
  347.     }
  348.  
  349.     class FastScanner {
  350.         BufferedReader br;
  351.         StringTokenizer st;
  352.  
  353.         public FastScanner(File f) {
  354.             try {
  355.                 br = new BufferedReader(new FileReader(f));
  356.             } catch (FileNotFoundException e) {
  357.                 e.printStackTrace();
  358.             }
  359.         }
  360.  
  361.         public FastScanner(InputStream f) {
  362.             br = new BufferedReader(new InputStreamReader(f));
  363.         }
  364.  
  365.         String next() {
  366.             while (st == null || !st.hasMoreTokens()) {
  367.                 String s = null;
  368.                 try {
  369.                     s = br.readLine();
  370.                 } catch (IOException e) {
  371.                     e.printStackTrace();
  372.                 }
  373.                 if (s == null)
  374.                     return null;
  375.                 st = new StringTokenizer(s);
  376.             }
  377.             return st.nextToken();
  378.         }
  379.  
  380.         boolean hasMoreTokens() {
  381.             while (st == null || !st.hasMoreTokens()) {
  382.                 String s = null;
  383.                 try {
  384.                     s = br.readLine();
  385.                 } catch (IOException e) {
  386.                     e.printStackTrace();
  387.                 }
  388.                 if (s == null)
  389.                     return false;
  390.                 st = new StringTokenizer(s);
  391.             }
  392.             return true;
  393.         }
  394.  
  395.         int nextInt() {
  396.             return Integer.parseInt(next());
  397.         }
  398.  
  399.         long nextLong() {
  400.             return Long.parseLong(next());
  401.         }
  402.  
  403.         double nextDouble() {
  404.             return Double.parseDouble(next());
  405.         }
  406.     }
  407.  
  408.     public static void main(String[] args) {
  409.         new Day2I().runIO();
  410.     }
  411. }
Advertisement
Add Comment
Please, Sign In to add comment