• HDOJ多校联合第五场


    1001 Inversion

    题意:求逆序对,然后交换k次相邻的两个数,使得剩下的逆序对最少。

    分析:题目用到的结论是:数组中存在一对逆序对,那么可以通过交换相邻两个数使得逆序对减少1,交换k次,可以最多减少k个。

    嘉定ai>aj,i < j,如果ai,aj相邻的,那么显然可以通过交换减少1;不相邻的情况,

    考虑ak,k = j-1;

    #11:ak > aj,那么ak,aj构成逆序对,交换后逆序对减少1;

    #12:ak<=aj,那么ai,ak构成逆序对,问题转化为更小规模,可以通过同样的方法进一步分析,最终一定能够交换一次使得逆序对减少1个;

    考虑ak,k = i+1;

    #21:ak<ai,那么ai,ak构成逆序对,可以交换;

    #22:ak>=ai那么ak,aj构成逆序对,问题规模缩小,和#12同样的处理方法。

    所以最终答案就是max(0LL, ans-k)嘛,

    代码:

    分治法

     1 //Template updates date: 20140718
     2 #include <iostream>
     3 #include <sstream>
     4 #include <cstdio>
     5 #include <climits>
     6 #include <ctime>
     7 #include <cctype>
     8 #include <cstring>
     9 #include <cstdlib>
    10 #include <string>
    11 #include <stack>
    12 #include <set>
    13 #include <map>
    14 #include <cmath>
    15 #include <vector>
    16 #include <queue>
    17 #include <algorithm>
    18 #define  esp 1e-6
    19 #define  inf 0x3f3f3f3f
    20 #define  pi acos(-1.0)
    21 #define  pb push_back
    22 #define  lson l, m, rt<<1
    23 #define  rson m+1, r, rt<<1|1
    24 #define  lowbit(x) (x&(-x))
    25 #define  mp(a, b) make_pair((a), (b))
    26 #define  bit(k) (1<<(k))
    27 #define  iin  freopen("pow.in", "r", stdin);
    28 #define  oout freopen("pow.out", "w", stdout);
    29 #define  in  freopen("solve_in.txt", "r", stdin);
    30 #define  out freopen("solve_out.txt", "w", stdout);
    31 #define  bug puts("********))))))");
    32 #define  Inout iin oout
    33 #define  inout in out
    34 
    35 #define  SET(a, v) memset(a, (v), sizeof(a))
    36 #define  SORT(a)   sort((a).begin(), (a).end())
    37 #define  REV(a)    reverse((a).begin(), (a).end())
    38 #define  READ(a, n) {REP(i, n) cin>>(a)[i];}
    39 #define  REP(i, n) for(int i = 0; i < (n); i++)
    40 #define  VREP(i, n, base) for(int i = (n); i >= (base); i--)
    41 #define  Rep(i, base, n) for(int i = (base); i < (n); i++)
    42 #define  REPS(s, i) for(int i = 0; (s)[i]; i++)
    43 #define  pf(x) ((x)*(x))
    44 #define  mod(n) ((n))
    45 #define  Log(a, b) (log((double)b)/log((double)a))
    46 #define Srand() srand((int)time(0))
    47 #define random(number) (rand()%number)
    48 #define random_range(a, b) (int)(((double)rand()/RAND_MAX)*(b-a) + a)
    49 
    50 using namespace std;
    51 typedef long long  LL;
    52 typedef unsigned long long ULL;
    53 typedef vector<LL> VI;
    54 typedef pair<int,int> PII;
    55 typedef vector<PII> VII;
    56 typedef vector<PII, int> VIII;
    57 typedef VI:: iterator IT;
    58 typedef map<string, int> Mps;
    59 typedef map<int, int> Mpi;
    60 typedef map<int, PII> Mpii;
    61 typedef map<PII, int> Mpiii;
    62 const int maxn = 100000 + 100;
    63 int a[maxn];
    64 int n, k;
    65 LL ans;
    66 int T[maxn];
    67 
    68 void solve(int l, int r) {
    69     if(l == r || l > r)
    70         return;
    71     int m = l+(r-l)/2;
    72     solve(l, m);
    73     solve(m+1, r);
    74     int p = l, q = m+1;
    75     int cnt = 0;
    76     while(p <= m || q <= r) {
    77         if(p > m|| (q <= r && a[q] < a[p]))
    78             T[cnt++] = a[q++];
    79         else {
    80             ans = ans + (q-m-1);
    81             T[cnt++] = a[p++];
    82         }
    83     }
    84     REP(i, cnt)
    85     a[l+i] = T[i];
    86 }
    87 int main() {
    88     
    89     while(scanf("%d%d", &n, &k) == 2) {
    90         ans = 0;
    91         Rep(i, 1, n+1) scanf("%d", a+i);
    92         solve(1, n);
    93         cout<<max(0LL, ans-k)<<endl;
    94     }
    95     return 0;
    96 }
    View Code

    树状数组写法:

     1 //Template updates date: 20140718
     2 #include <iostream>
     3 #include <sstream>
     4 #include <cstdio>
     5 #include <climits>
     6 #include <ctime>
     7 #include <cctype>
     8 #include <cstring>
     9 #include <cstdlib>
    10 #include <string>
    11 #include <stack>
    12 #include <set>
    13 #include <map>
    14 #include <cmath>
    15 #include <vector>
    16 #include <queue>
    17 #include <algorithm>
    18 #define  esp 1e-6
    19 #define  inf 0x3f3f3f3f
    20 #define  pi acos(-1.0)
    21 #define  pb push_back
    22 #define  lson l, m, rt<<1
    23 #define  rson m+1, r, rt<<1|1
    24 #define  lowbit(x) (x&(-x))
    25 #define  mp(a, b) make_pair((a), (b))
    26 #define  bit(k) (1<<(k))
    27 #define  iin  freopen("pow.in", "r", stdin);
    28 #define  oout freopen("pow.out", "w", stdout);
    29 #define  in  freopen("solve_in.txt", "r", stdin);
    30 #define  out freopen("solve_out.txt", "w", stdout);
    31 #define  bug puts("********))))))");
    32 #define  Inout iin oout
    33 #define  inout in out
    34 
    35 #define  SET(a, v) memset(a, (v), sizeof(a))
    36 #define  SORT(a)   sort((a).begin(), (a).end())
    37 #define  REV(a)    reverse((a).begin(), (a).end())
    38 #define  READ(a, n) {REP(i, n) cin>>(a)[i];}
    39 #define  REP(i, n) for(int i = 0; i < (n); i++)
    40 #define  VREP(i, n, base) for(int i = (n); i >= (base); i--)
    41 #define  Rep(i, base, n) for(int i = (base); i < (n); i++)
    42 #define  REPS(s, i) for(int i = 0; (s)[i]; i++)
    43 #define  pf(x) ((x)*(x))
    44 #define  mod(n) ((n))
    45 #define  Log(a, b) (log((double)b)/log((double)a))
    46 #define Srand() srand((int)time(0))
    47 #define random(number) (rand()%number)
    48 #define random_range(a, b) (int)(((double)rand()/RAND_MAX)*(b-a) + a)
    49 
    50 using namespace std;
    51 typedef long long  LL;
    52 typedef unsigned long long ULL;
    53 typedef vector<LL> VI;
    54 typedef pair<int,int> PII;
    55 typedef vector<PII> VII;
    56 typedef vector<PII, int> VIII;
    57 typedef VI:: iterator IT;
    58 typedef map<string, int> Mps;
    59 typedef map<int, int> Mpi;
    60 typedef map<int, PII> Mpii;
    61 typedef map<PII, int> Mpiii;
    62 const int maxn = 100000 + 100;
    63 int a[maxn];
    64 int r[maxn], pos[maxn];
    65 int n, k;
    66 LL sum[maxn];
    67 bool cmp(int v1, int v2) {
    68     return a[v1] < a[v2] || (a[v1] == a[v2] && v1 < v2);
    69 }
    70 void update(int x) {
    71     while(x <= n) {
    72         sum[x] += 1;
    73         x += lowbit(x);
    74     }
    75 }
    76 LL getsum(int x) {
    77     LL ans = 0;
    78     while(x > 0) {
    79         ans += sum[x];
    80         x -= lowbit(x);
    81     }
    82     return ans;
    83 }
    84 int main() {
    85     
    86     while(scanf("%d%d", &n, &k) == 2) {
    87         Rep(i, 1, n+1) scanf("%d", a+i), r[i] = i, sum[i] = 0;
    88         sort(r+1, r+n+1, cmp);
    89         Rep(i, 1, n+1)
    90         pos[r[i]] = i;
    91         LL ans = 0;
    92         Rep(i, 1, n+1) {
    93             update(r[i]);
    94             ans += i-getsum(r[i]);
    95         }
    96         cout<<max(0LL, ans-k)<<endl;
    97     }
    98     return 0;
    99 }
    View Code

     

    1004 Linear recursive sequence

     题意:根据公式求指定某一项

    题解分析在这里。

     http://www.cnblogs.com/rootial/p/3920599.html

    1007 Permutation

    题意:给定n个数(n<=40),以及m种关系即第ai个数必须小于第bi个数,求这样的排列有多少个?

    分析:m种关系显然构成一个拓扑图,且各个连通图之间互相独立,因此单个考虑每个连通图的可能性,比如一个连通图中有k个点,

    从n个数中任选k个数,然后求这个图中能有多少个安排方案满足拓扑关系。

    研究标程,具体实现是,通过并查集找出连通关系,(话说一直没这么用过,还想着去dfs求,弱菜),然后重新编号,通过cover[i] 表示从点i出发的能到达的点,先用于i有直接变得点初始化,然后floyd求连通性。

    具体dp时,转移时这样的,dp[st|1<<i] += dp[st], st 满足(st&1<<i) == 0 && (st&cover[i]) == cover[i].

    代码:

    1009 Exclusive or

    题意 :求f(n) = Sum{i^(n-i)| 1<=i <= n-1}.

    分析:

    此题关键在于对奇数和偶数分开求递推公式。

    若n为偶数,设n = 2*k, 1<=i <= 2*k-1,分别考虑i为奇数和i为偶数时的值。

    f(n) = i为奇数时+i为偶数 = sum{(2*i-1)^(n-(2*i-1))| 1<= i <= k} + sum{(2*i)^(n-2*i)| 1 <= i <= k-1}

          = sum{(2*i-1)^(2*k-2*i+1)|1<=i <=k} + sum{(2*i)^(2*(k-i))| 1 <= i <= k-1}

      = sum{(2*(i-1))^(2*(k-i))|1<= i <= k} +  2*sum{i^(k-i)| 1 <= i <= k-1}

      = 2*sum{(i-1)^(k-i)|1<= i <= k} + 2*f(k)

      = 2*sum{(i-1)^(k-1-(i-1)) | 1 <= i <= k} + 2*f(k)

      = 2*sum{i^(k-1-i) | 0 <= i <= k-1} + 2*f(k)

      = 2*f(k-1)+2*f(k)+4*k-4

    若n为奇数,令n = 2*k+1, 1 <= i <= 2*k, 同样分析可得f(n) = 4*f(k) + 6*k.

    然后利用大数算出即可。

    代码:

      1 #pragma comment(linker, "/STACK:167772160")
      2 #include <cstdio>
      3 #include <iostream>
      4 #include <cstring>
      5 #include <string>
      6 #include <cstdlib>
      7 #include <algorithm>
      8 #include <vector>
      9 #include <queue>
     10 #include <map>
     11 #include <set>
     12 #define in freopen("solve_in.txt", "r", stdin);
     13 #define Rep(i, base, n) for(int i = (base); i < n; i++)
     14 #define REP(i, n) for(int i = 0; i < (n); i++)
     15 #define REPS(s, i) for(int i = 0; (s)[i]; i++)
     16 #define  VREP(i, n, base) for(int i = (n); i >= (base); i--)
     17 #define SET(a, n) memset(a, (n), sizeof(a));
     18 #define pb push_back
     19 #define mp make_pair
     20 
     21 using namespace std;
     22 typedef vector<unsigned  short> VI;
     23 typedef pair<unsigned  short, unsigned  short> PII;
     24 typedef vector<PII> VII;
     25 typedef long long LL;
     26 const int maxn = 500;
     27 const int B = 10000;
     28 
     29 struct BigInt {
     30     int dig[maxn], len;
     31     BigInt(int num = 0):len(!!num) {
     32         memset(dig, 0, sizeof dig);
     33         dig[0] = num;
     34     }
     35     int operator[] (int index)const {
     36         return dig[index];
     37     }
     38     int& operator[] (int index) {
     39         return dig[index];
     40     }
     41     BigInt normalize() {
     42         while(len && dig[len-1] == 0)
     43             len--;
     44         return *this;
     45     }
     46     void output() {
     47         if(len == 0) {
     48             cout<<0<<endl;
     49             return;
     50         }
     51         printf("%d", dig[len-1]);
     52         for(int i = len-2; i >= 0; i--)
     53             printf("%04d", dig[i]);
     54         cout<<endl;
     55     }
     56 };
     57 bool operator < (const BigInt &a, const BigInt &b) {
     58     if(a.len != b.len) return a.len < b.len;
     59     for(int i = a.len-1; i >= 0; i--) if(a[i] != b[i])
     60             return a[i] < b[i];
     61     return false;
     62 }
     63 BigInt operator + (const BigInt &a, const BigInt &b) {
     64     BigInt c;
     65     c.len = max(a.len, b.len)+1;
     66     for(int i = 0, delta = 0; i < c.len; i++) {
     67         delta += a[i]+b[i];
     68         c[i] = delta%B;
     69         delta /= B;
     70     }
     71     return c.normalize();
     72 }
     73 BigInt operator - (const BigInt &a, const int &b) {
     74     BigInt c;
     75     c.len = a.len;
     76     for(int i = 0, delta = -b; i < c.len; i++) {
     77         delta += a[i];
     78         c[i] = delta;
     79         delta = 0;
     80         if(c[i] < 0) {
     81             c[i] += B;
     82             delta = -1;
     83         }
     84     }
     85     return c.normalize();
     86 }
     87 BigInt operator * (const BigInt &a, const BigInt &b) {
     88     BigInt c;
     89     c.len = a.len+b.len+1;
     90     for(int i = 0; i < a.len; i++)
     91         for(int j = 0, delta = 0; j <= b.len; j++) {
     92             delta += a[i]*b[j]+c[i+j];
     93             c[i+j] = delta%B;
     94             delta /= B;
     95         }
     96     return c.normalize();
     97 }
     98 BigInt operator / (const BigInt &a, const int &b) {
     99     BigInt c;
    100     c.len = a.len;
    101     for(int i = a.len-1, delta = 0; i >= 0; i--) {
    102         delta = a[i] + delta*B;
    103         c[i] = delta/b;
    104         delta %= b;
    105     }
    106     return c.normalize();
    107 }
    108 char s[1000];
    109 typedef map<BigInt, BigInt> MPS;
    110 MPS mps;
    111 
    112 BigInt solve(BigInt n) {
    113     BigInt nn;
    114     nn = n/2;
    115 //    n.output();
    116 //    nn.output();
    117     if(!mps.count(n)) {
    118         if(n[0]&1) {
    119             mps[n] = solve(nn)*4 + nn*6;
    120         } else {
    121             mps[n] = solve(nn-1)*2+solve(nn)*2+nn*4-4;
    122         }
    123     }
    124     return mps[n];
    125 }
    126 int tmp[] = {1, 10, 100, 1000};
    127 
    128 int main() {
    129 
    130     mps[2] = 0;
    131     mps[1] = 0;
    132     mps[3] = 6;
    133     mps[0] = 0;
    134     while(scanf("%s", s) == 1) {
    135         BigInt x;
    136         int len = strlen(s);
    137         reverse(s, s+len);
    138         for(int i = 0; i < len; i++) {
    139             int id = i/4+1;
    140             x.len = max(x.len, id);
    141             x[id-1] = x[id-1] + (s[i]-'0')*tmp[i%4];
    142         }
    143         solve(x).output();
    144     }
    145     return 0;
    146 }
    View Code

     1010 Matrix multiplication

     题意: 2个n*n的矩阵,输出相乘后每个元素对3取模后矩阵。

    分析:输入时对每个元素取模,则剩下1*1,1*2,2*1,2*2这几种相乘情况,利用bitset,将相应的为1,2 的元素单独拿出来考虑,然后按照上面4种情况,分别求出相乘后的结果,最后加起来取模。

    ADD:学习了一下bitset位集的使用。

    代码:

     1 #include <iostream>
     2 #include <bitset>
     3 #include <cstdio>
     4 #define in freopen("solve_in.txt", "r", stdin);
     5 
     6 using namespace std;
     7 const int maxn =810;
     8 bitset<maxn> b[2][2][maxn];
     9 int n;
    10 
    11 int main() {
    12     
    13     while(~scanf("%d", &n)) {
    14         for(int k = 0; k < 2; k++)
    15             for(int i = 0; i < n; i++)
    16                 for(int j = 0; j < n; j++) {
    17                     int t;
    18                     scanf("%d", &t);
    19                     t %= 3;
    20                     if(k == 1) {
    21                         b[k][0][j][i] = b[k][1][j][i] = 0;
    22                         if(t == 1)
    23                             b[k][0][j][i] = 1;
    24                         else if(t == 2)
    25                             b[k][1][j][i] = 1;
    26                     } else {
    27                         b[k][0][i][j] = b[k][1][i][j] = 0;
    28                         if(t == 1)
    29                             b[k][0][i][j] = 1;
    30                         else if(t == 2)
    31                             b[k][1][i][j] = 1;
    32                     }
    33                 }
    34         for(int i = 0; i < n; i++)
    35             for(int j = 0; j < n; j++) {
    36                 int t1 = (b[0][0][i]&b[1][0][j]).count();
    37                 int t2 = (b[0][0][i]&b[1][1][j]).count()*2;
    38                 int t3 = (b[0][1][i]&b[1][0][j]).count()*2;
    39                 int t4 = (b[0][1][i]&b[1][1][j]).count();
    40                 int ans = (t1+t2+t3+t4)%3;
    41                 printf("%d%c", ans, j == n-1 ? '
    ' : ' ');
    42             }
    43     }
    44     return 0;
    45 }
    View Code
  • 相关阅读:
    mysql_Navicat数据库破解
    SpringBoot+ Mybatis 搭建
    SSH框架搭建
    SSM 框架搭建
    android 网络_网络图片查看器
    android 网络_网络源码查看器
    android ListView_显示数据库数据
    android ListView_新闻案例
    android ListView的怪异现象
    android ListView_Tiger
  • 原文地址:https://www.cnblogs.com/rootial/p/3893435.html
Copyright © 2020-2023  润新知