zoukankan      html  css  js  c++  java
  • Codeforce 380A Sereja and Prefixes【二分】

    题意:定义两种操作

    • 1 a ---- 向序列中插如一个元素a
    • 2 a b ---- 将序列的前a个元素[e1,e2,...,ea]重复b次插入到序列中

    经过一列操作后,为处于某个位置p的元素是多少。数据范围共有105以内的操作,形成序列中的元素总个数大小不超过64bit长整型表示。

    思考:只需要记录两种操作这些关键元素的位置,如果查询的坐标位置刚好是第一种产生的,那么直接就知道结果了;如果查询的是第二种操作产生的,它是由前a个元素重复b次而来,它来自前a个元素,依次递归向前找,直到找到第一种情况。

    1 const int maxn = 100005;
    2 __int64 pos[maxn];
    3 __int64 val[maxn];
    4 int flag[maxn];

    可能用struct放到一起更直观一些。

    flag用来标记,当前元素如果为1,则为第一种操作产生,pos此时记录当前元素位置,val记录当前元素的值。

    flag为0时候,则为第二种操作产生,pos记录第二种操作开始的元素位置,val记录a,即序列的前a个元素,这个长度a。

    知道这些我们就好办了,用二分,LowBound去找序列中查询元素位置在pos中的下界。然后根据flag来判断是否需要递归继续往下找,或是返回找到的结果。

     1 __int64 GetResult(__int64 key) {
     2     int l = 0, r = len-1;
     3     while (l <= r) {
     4         int m = (l+r) >> 1;
     5         if (pos[m] == key) {
     6             if (flag[m])    return val[m];
     7             else return GetResult((key-pos[m]+1)%val[m] != 0 ? ((key-pos[m]+1)%val[m]) : val[m]);
     8         } else if (pos[m] < key) {
     9             l = m+1;
    10         } else {
    11             r = m-1;
    12         }
    13     }
    14     return GetResult((key-pos[r]+1)%val[r] != 0 ? ((key-pos[r]+1)%val[r]) : val[r]);
    15 }

    下面是完整代码:

      1 #define _CRT_SECURE_NO_DEPRECATE
      2 #define _SECURE_SCL 0
      3 #pragma comment(linker, "/STACK:66777216")
      4 #include <algorithm>
      5 #include <string>
      6 #include <complex>
      7 #include <cassert>
      8 #include <memory>
      9 #include <set>
     10 #include <stack>
     11 #include <map>
     12 #include <list>
     13 #include <deque>
     14 #include <numeric>
     15 #include <cctype>
     16 #include <cstddef>
     17 #include <vector>
     18 #include <queue>
     19 #include <iostream>
     20 #include <iomanip>
     21 #include <iterator>
     22 #include <cmath>
     23 #include <cstdio>
     24 #include <cstdlib>
     25 #include <sstream>
     26 #include <fstream>
     27 #include <ctime>
     28 #include <cstring>
     29 #include <functional>
     30 #include <bitset>
     31 using namespace std;
     32  
     33 #if defined(_MSC_VER) || defined(__BORLANDC__)
     34     typedef unsigned __int64 uint64;
     35     typedef signed __int64 int64;
     36 #else
     37     typedef unsigned long long uint64;
     38     typedef signed long long int64;
     39 #endif
     40 typedef vector<int> VI;
     41 typedef vector<string> VS;
     42 typedef pair<int,int> PII;
     43 typedef pair<int64,int64> PLL;
     44 typedef vector<int64> VL;
     45  
     46 #define pb push_back
     47 #define ppb pop_back
     48 #define mp make_pair
     49 #define fi first
     50 #define se second
     51 #define pii pair<int,int>
     52 #define pdd pair<double,double>
     53 #define FOR(i,a,b) for (int _n(b), i(a); i <= _n; i++)
     54 #define FORD(i,a,b) for(int i=(a),_b=(b);i>=_b;i--)
     55 #define all(c) (c).begin(), (c).end()
     56 #define SORT(c) sort(all(c))
     57 #define REP(i,n) FOR(i,1,(n))
     58 #define REPT(i,n) FOR(i,0,(n)-1)
     59 #define L(s) (int)((s).size())
     60 #define C(a) memset((a),0,sizeof(a))
     61 #define IOS ios::sync_with_stdio(false)
     62  
     63 const double pi = 3.1415926535897932384626433832795028841971;
     64 const double EPS = 1E-9;
     65 const int64 INF64 = (int64)1E18;
     66 const int INF = 1000000000;
     67 
     68 static inline bool get(int &v) {
     69     int s = 1, c;
     70     while(!isdigit(c = getchar())&&c != '-')
     71         if(c == EOF)    break ;
     72 
     73     if(c == EOF) return 0;
     74     if(c == '-') s = 0 , v = 0;
     75     else v = c^48;
     76     for(;isdigit(c = getchar());v = (v << 1) + (v << 3) + (c ^ 48));
     77     v = (s ? v : -v);
     78     return 1 ;
     79 }
     80 int len = 0;
     81 const int maxn = 100005;
     82 __int64 pos[maxn];
     83 __int64 val[maxn];
     84 int flag[maxn];
     85 
     86 __int64 GetResult(__int64 key) {
     87     int l = 0, r = len-1;
     88     while (l <= r) {
     89         int m = (l+r) >> 1;
     90         if (pos[m] == key) {
     91             if (flag[m])    return val[m];
     92             else return GetResult((key-pos[m]+1)%val[m] != 0 ? ((key-pos[m]+1)%val[m]) : val[m]);
     93         } else if (pos[m] < key) {
     94             l = m+1;
     95         } else {
     96             r = m-1;
     97         }
     98     }
     99     return GetResult((key-pos[r]+1)%val[r] != 0 ? ((key-pos[r]+1)%val[r]) : val[r]);
    100 }
    101 
    102 
    103 void run() {
    104     int m, n, op;
    105     __int64 e, l, c, v = 1;
    106     cin >> m;
    107     FOR(i, 1, m) {
    108         cin >> op;
    109         if (op == 1) {
    110             cin >> e;
    111             pos[len] = v;
    112             val[len] = e;
    113             flag[len] = 1;
    114             len += 1;
    115             v++;
    116         } else {
    117             cin >> l >> c;
    118             pos[len] = v;
    119             val[len] = l;
    120             flag[len] = 0;
    121             v = l*c + pos[len];
    122             len += 1;
    123         }
    124     }
    125     __int64 key;
    126     cin >> n;
    127     FOR(i, 1, n) {
    128         cin >> key;
    129         cout << GetResult(key) << " ";
    130     }
    131     cout << endl;
    132 }
    133 
    134  
    135   
    136 int main() {
    137 #ifdef __DEBUG__
    138     freopen("test.in","r",stdin);
    139     freopen("test.out","w",stdout);
    140     time_t st = clock();
    141 #endif
    142     run();
    143 #ifdef __DEBUG__
    144     printf( "
    =============
    ");
    145     printf("Time: %.2lf sec
    ",(clock()-st)/double(CLOCKS_PER_SEC));
    146 #endif
    147     return 0;
    148 }
    View Code
  • 相关阅读:
    进制间转换的理论和实现不同
    操作DOM
    浏览器对象
    浏览器
    面向对象编程——class继承
    面向对象编程——原型继承
    js面向对象编程——创建对象
    JS面向对象编程
    js的JSON
    js标准对象——Date
  • 原文地址:https://www.cnblogs.com/tiny656/p/3549908.html
Copyright © 2011-2022 走看看