zoukankan      html  css  js  c++  java
  • 某模拟题题解


      第一题就是一个很简单的dp,这么想就很好想出dp方程了

    前面的序列是有1到(i - 1)组成,将i插在最前面,将会增加i - 1个逆序对

    如果插在第一个数的后面,将会增加i - 2个逆序对。。。以此类推

      于是得到了dp方程:

    f[i][j] = f[i - 1][max(j - i + 1, 0)] + f[i - 1][max(j - i + 1, 0) + 1] + ... + f[i - 1][min((i - 1) * (i - 2) / 2, j)];

      有一点长,也可以用f[i][j - 1]来状态转移,这样方程很简单得多,

    但是要注意“分类讨论”

      但我用的是第一种方程,如果直接这么做的话,时间复杂度大概是O(n2k)

    这样数据是过不完的,所以要加一个前缀和优化,就直接看代码了吧。。

    Code

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<cctype>
     6 #include<cstdlib>
     7 #include<map>
     8 #include<set>
     9 #include<queue>
    10 #include<stack>
    11 using namespace std;
    12 typedef bool boolean;
    13 #define smin(a, b)    (a) = min((a), (b))
    14 #define smax(a, b)    (a) = max((a), (b))
    15 template<typename T>
    16 inline void readInteger(T& u){
    17     char x;
    18     while(!isdigit((x = getchar())));
    19     for(u = x - '0'; isdigit((x = getchar())); u = (u << 1) + (u << 3) + x - '0');
    20     ungetc(x, stdin);
    21 }
    22 
    23 template<typename T>class Matrix{
    24     public:
    25         T* p;
    26         int rows;
    27         int lines;
    28         Matrix():p(NULL), rows(0), lines(0){}
    29         Matrix(int rows, int lines):rows(rows), lines(lines){
    30             p = new T[rows * lines];
    31         }
    32         T* operator [](int pos){
    33             return p + lines * pos;
    34         }
    35 };
    36 
    37 #define matset(m, i, s)    memset((m).p, i, s * (m).rows * (m).lines)
    38 
    39 int T;
    40 Matrix<int>    f;
    41 Matrix<int>    s;
    42 int n, k;
    43 
    44 #define limit(i)    (((i) * (i - 1)) >> 1)
    45 
    46 int adder(int a, int b){
    47     return (a + b) % 10000;
    48 }
    49 
    50 inline void dp(){
    51     f[1][0] = 1;
    52     s[1][0]    = 1;
    53     for(int i = 2; i <= n; i++){
    54         f[i][0] = 1;
    55         s[i][0] = 1;
    56         for(int j = 1; j <= limit(i) && j <= k; j++){
    57             if(j - i + 1 <= 0){
    58                 f[i][j] = s[i - 1][min(limit(i - 1), j)];
    59             }else{
    60                 f[i][j] = (s[i - 1][min(limit(i - 1), j)] - s[i - 1][j - i] + 10000) % 10000;
    61             }
    62             s[i][j] = adder(s[i][j - 1], f[i][j]);
    63         }
    64     }
    65 }
    66 
    67 inline void solve(){
    68     readInteger(T);
    69     while(T--){
    70         readInteger(n);
    71         readInteger(k);
    72         if(k > n * (n - 1) / 2){
    73             printf("0
    ");
    74             continue;
    75         }
    76         f = Matrix<int>(n + 1, k + 1);
    77         s = Matrix<int>(n + 1, k + 1);
    78         dp();
    79         printf("%d
    ", f[n][k]);
    80         delete f.p;
    81         delete s.p;
    82     }
    83 }
    84 
    85 int main(){
    86     freopen("permut.in", "r", stdin);
    87     freopen("permut.out", "w", stdout);
    88     solve();
    89     return 0;
    90 }


      抛开中位数什么的不说,就是一道区间最大值的裸题,倍增,RMQ,线段树都可以解决

    至于求中位数嘛。。你可以把它从(i + 1)至右扫一遍,记录每个地方它所需要的比ai大(或小)的个数

    (重复了话,直接覆盖,反正你要的是最长的区间),再从i往左扫一遍,能够补上的就用算出长度,更新

    就行了

    Code

      1 #include<iostream>
      2 #include<algorithm>
      3 #include<cstdio>
      4 #include<cstring>
      5 #include<cctype>
      6 #include<cstdlib>
      7 #include<map>
      8 #include<set>
      9 #include<queue>
     10 #include<stack>
     11 using namespace std;
     12 typedef bool boolean;
     13 #define smin(a, b)    (a) = min((a), (b))
     14 #define smax(a, b)    (a) = max((a), (b))
     15 template<typename T>
     16 inline void readInteger(T& u){
     17     char x;
     18     while(!isdigit((x = getchar())));
     19     for(u = x - '0'; isdigit((x = getchar())); u = (u << 1) + (u << 3) + x - '0');
     20     ungetc(x, stdin);
     21 }
     22 
     23 template<typename T>class Matrix{
     24     public:
     25         T* p;
     26         int rows;
     27         int lines;
     28         Matrix():p(NULL), rows(0), lines(0){}
     29         Matrix(int rows, int lines):rows(rows), lines(lines){
     30             p = new T[rows * lines];
     31         }
     32         T* operator [](int pos){
     33             return p + lines * pos;
     34         }
     35 };
     36 
     37 #define matset(m, i, s)    memset((m).p, i, s * (m).rows * (m).lines)
     38 
     39 int n, q;
     40 int* buti;
     41 int* list;
     42 //int power[12] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048};
     43 Matrix<int>    upper;
     44 Matrix<int>    maxer;
     45 
     46 inline void init(){
     47     readInteger(n);
     48     list = new int[(const int)(n + 1)];
     49     buti = new int[(const int)(n + 1)];
     50     for(int i = 1; i <= n; i++){
     51         readInteger(list[i]);
     52     }
     53 }
     54 
     55 inline int calc(int less, int more){
     56     return (less < more) ? (n - less + more) : (less - more);
     57 }
     58 
     59 int* buffer;
     60 inline void getButi(){
     61     buffer = new int[(const int)(2 * n + 1)];
     62     for(int i = 1; i <= n; i++){
     63         int len = 1;
     64         int less = 0;
     65         int more = 0;
     66         memset(buffer, 0, sizeof(int) * (2 * n + 1));
     67         buffer[0] = i;
     68         for(int j = i + 1; j <= n; j++){
     69             if(list[j] >= list[i])    more++;
     70             else less++;
     71             buffer[calc(less, more)] = j;
     72         }
     73         less = more = 0;
     74         for(int j = i; j >= 1; j--){
     75             if(list[j] > list[i])    more++;
     76             else if(i != j)    less++;
     77             if(buffer[calc(more, less)]){
     78                 smax(len, buffer[calc(more, less)] - j + 1);
     79             }    
     80         }
     81         buti[i] = len;
     82     }
     83 }
     84 
     85 inline void init_bz(){
     86     upper = Matrix<int>(n + 1, 13);
     87     maxer = Matrix<int>(n + 1, 13);
     88     matset(upper, 0, sizeof(int));
     89     matset(maxer, 0, sizeof(int));
     90     buti[0] = 0;
     91     for(int i = 1; i < n; i++){
     92         maxer[i][0] = max(buti[i], buti[i + 1]);
     93         upper[i][0] = i + 1;
     94     }
     95     maxer[n][0] = buti[n];
     96     for(int j = 1; j <= 11; j++){
     97         for(int i = 1; i <= n; i++){
     98             upper[i][j] = upper[upper[i][j - 1]][j - 1];
     99             maxer[i][j] = max(maxer[i][j - 1], maxer[upper[i][j - 1]][j - 1]);
    100         }
    101     }
    102 }
    103 
    104 inline void solve(){
    105     readInteger(q);
    106     for(int i = 1, l, r; i <= q; i++){
    107         readInteger(l);
    108         readInteger(r);
    109         int ct = r - l;
    110         if(ct == 0){
    111             printf("%d
    ", buti[l]);
    112         }else{
    113             int result = buti[l];
    114             for(int j = 0; j <= 11 && ct; j++){
    115                 if(ct & 1){
    116                     smax(result, maxer[l][j]);
    117                     l = upper[l][j];
    118                 }
    119                 ct >>= 1;
    120             }
    121             printf("%d
    ", result);
    122         }
    123     }
    124 }
    125 
    126 int main(){
    127     freopen("beautiful.in", "r", stdin);
    128     freopen("beautiful.out", "w", stdout);
    129     init();
    130     getButi();
    131     init_bz();
    132     solve();
    133     return 0;
    134 }


      这道题呢,可以用一个s[216]数组来存,把每个数及其“子集”(就是and的时候如果s某一二进制

    位上是1,但是a的这一位为0,虽然仍然and完了这一位是0,但是计算的时候你需要把这些情况都计

    算一下,再通俗一点就是这个and 原数不变),这样的话,删除和插入的时间复杂度是O(216),但查

    询的时间复杂度是O(1)。

      这样做的话,如果遇到那种极不平衡的数据就死翘翘了[滑稽]

      所以可以把s数组分成2部分s[pre][suf],表示一个数的高八位为pre,低8位是suf的“子集”,

    插入和删除只需要考虑低八位,而查询就枚举高八位and s,这样时间复杂度就很平衡了,都是O(28

     1 #include<iostream>
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<cstdio>
     5 #include<cstring>
     6 #include<cctype>
     7 #include<cstdlib>
     8 #include<map>
     9 #include<set>
    10 #include<queue>
    11 #include<stack>
    12 using namespace std;
    13 typedef bool boolean;
    14 #define smin(a, b)    (a) = min((a), (b))
    15 #define smax(a, b)    (a) = max((a), (b))
    16 template<typename T>
    17 inline void readInteger(T& u){
    18     char x;
    19     while(!isdigit((x = getchar())));
    20     for(u = x - '0'; isdigit((x = getchar())); u = (u << 1) + (u << 3) + x - '0');
    21     ungetc(x, stdin);
    22 }
    23 
    24 const int limit = 255;
    25 
    26 int n;
    27 char cmd[10];
    28 int s[limit + 1][limit + 1];
    29 
    30 inline void update(int x, int value){
    31     int pre = x >> 8, suf = x & limit, comp = suf ^ limit;
    32     s[pre][suf] += value;
    33     for(int i = comp; i != 0; i = (i - 1) & comp){
    34         s[pre][suf | i] += value;
    35     }
    36 }
    37 
    38 inline int query(int x){
    39     int suf = x & limit, result = s[0][suf], pre = x >> 8;
    40     for(int i = pre; i != 0; i = (i - 1) & pre){
    41         result += s[i][suf];
    42     }
    43     return result;
    44 }
    45 
    46 inline void solve(){
    47     readInteger(n);
    48     for(int i = 1, x; i <= n; i++){
    49         getchar();
    50         scanf("%s", cmd);
    51         readInteger(x);
    52         if(cmd[0] == 'a' || cmd[0] == 'd'){
    53             update(x, ((cmd[0] == 'a') ? (1) : (-1)));
    54         }else{
    55             printf("%d
    ", query(x));
    56         }
    57     }
    58 }
    59 
    60 int main(){
    61     freopen("subset.in", "r", stdin);
    62     freopen("subset.out", "w", stdout);
    63     solve();
    64     return 0;
    65 }
  • 相关阅读:
    HU 参考错误修正:/SCWM/RCORR_HUREF
    EWM 强大的数据修复功能
    EWM ODO清理功能
    发布EWM RF ITS Mobile 相关服务
    git上传本地Intellij idea 项目到码云的git仓库中
    linux 学习一:安装jdk和tomcat
    bootstrap-datepicker应用
    vue2 枚举类型转换
    jqGrid时间转换
    (原创)Rocketmq分布式消息队列的部署与监控
  • 原文地址:https://www.cnblogs.com/yyf0309/p/6011107.html
Copyright © 2011-2022 走看看