zoukankan      html  css  js  c++  java
  • wap 5.23 网测几道题目

    1. n个犯人,m个省份, 如果相邻的2个犯人来自同一省份,则是不安全的,求不安全的个数。

    正难则反,用全部的个数减去非法的个数,就是最后的答案。 m^n - m * (m - 1) ^ (n - 1).  这里的m,n很大,所以就是快速幂乘法。

     1 #include<bits/stdc++.h>
     2 #define pb push_back
     3 typedef long long ll;
     4 using namespace std;
     5 typedef pair<int, int> pii;
     6 const int maxn = 1e3 + 10;
     7 const int mod = 100003;
     8 ll n, m;
     9 ll pow(ll x, ll y) {
    10     if(y == 0) return 1;
    11     ll r = 1;
    12     ll b = x;
    13     while(y) {
    14         if(y & 1) {
    15             r = r * b % mod;
    16         }
    17         y >>= 1;
    18         b = b * b % mod;
    19     }
    20     return r;
    21 }
    22 void solve() {
    23     cin >> m >> n;
    24     //cout << m<< " " << n <<endl;
    25     //cout << pow(m, n) << endl;
    26     //cout << pow(m, n - 1) << endl;
    27     ll res = ((pow(m, n) - pow(m - 1, n - 1) * m) % mod + mod)%mod;
    28     cout << res << endl;
    29 }
    30 
    31 int main() {
    32     freopen("test.in", "r", stdin);
    33     //freopen("test.out", "w", stdout);
    34     ios::sync_with_stdio(0);
    35     cin.tie(0); cout.tie(0);
    36     solve();
    37     return 0;
    38 }
    View Code

    2. 从n个数,选取一些数,使得能被m整除。

    这种题,就是一般的套路, 搞一下余数, 然后就是0,1背包。注意一维数组优化,滚动数组, 取余。

     1 #include<bits/stdc++.h>
     2 #define pb push_back
     3 typedef long long ll;
     4 using namespace std;
     5 typedef pair<int, int> pii;
     6 const int maxn = 1e6 + 10;
     7 int n, m;
     8 int a[maxn];
     9 void yes() {
    10     cout << "Yes" << endl;
    11 }
    12 void no() {
    13     cout << "No" << endl;
    14 }
    15 int dp[2][maxn];
    16 void solve() {
    17     scanf("%d%d", &n, &m);
    18     int x, y;
    19     for (int i = 0; i < n; i++) {
    20         scanf("%d", &x);
    21         x = x % m;
    22         a[x]++;
    23     }
    24     if(a[0] > 0) {
    25         yes(); return;
    26     }
    27 
    28     dp[0][0] = 1;
    29     vector<int> av;
    30     for (int i = 1; i <= m - 1; i++) {
    31         for (int j = 0; j < a[i]; j++)
    32             av.push_back(i);
    33             //cout << i << endl;
    34     }
    35     //cout << "asd" << endl;
    36     int cur = 0, nxt = 1;
    37     for (int tx : av) {
    38         for (int i = m - 1; i >= 0; i--) {
    39             if(dp[cur][i] > 0) {
    40                 dp[nxt][i] = 1;
    41                 int t = (i + tx) % m;
    42                 if(t == 0) t = m;
    43                 dp[nxt][t] = 1;
    44                 //cout << t << endl;
    45             }
    46         }
    47         swap(cur, nxt);
    48         for (int i = 0; i < m; i++)
    49             dp[nxt][i] = 0;
    50         //cout << tx << endl;
    51     }
    52 
    53     if(dp[cur][m]) yes();
    54     else no();
    55 }
    56 
    57 int main() {
    58     freopen("test.in", "r", stdin);
    59     //freopen("test.out", "w", stdout);
    60     solve();
    61     return 0;
    62 }
    View Code

    3. 有一些操作,插入和查询,插入是往末尾进行插入,查找的是末尾长度为l的里面的最大值。

    由于每次动态更新,区间不停的变换,我只想到线段树的做法,就写了线段树的。logn单点更新, logn区间查询。

     1 #include<bits/stdc++.h>
     2 #define pb push_back
     3 typedef long long ll;
     4 using namespace std;
     5 typedef pair<int, int> pii;
     6 const int maxn = 2e5 + 10;
     7 ll f[maxn * 4];
     8 int n;
     9 int x, y;
    10 ll v;
    11 void bt(int o, int left, int right) {
    12 }
    13 void add(int o, int left, int right) {
    14     if(left > right) return;
    15     if(left == right && left == x) {
    16         f[o] = v;
    17     } else {
    18         int mid = (left + right) / 2;
    19         if(x <= mid) add(o * 2, left, mid);
    20         else add(o * 2 + 1, mid + 1, right);
    21         f[o] = max(f[o * 2], f[o * 2 + 1]);
    22     }
    23 }
    24 ll ask(int o, int left, int right) {
    25     if(right < x || y < left) return 0;
    26     if(x <= left && right <= y) return f[o];
    27     int mid = (left + right) / 2;
    28     ll ml, mr;ml = mr = 0;
    29     if(x <= mid) ml = ask(o * 2, left, mid);
    30     if(y >= mid + 1) mr = ask(o * 2 + 1, mid + 1, right);
    31     return max(ml, mr);
    32 }
    33 int m;
    34 ll mod;
    35 char ch[5];
    36 void solve() {
    37     scanf("%d%lld", &m, &mod);
    38     int p = 0;
    39     ll lst = 0, t;
    40     for (int i = 0; i < m; i++) {
    41         //cout << i << endl;
    42         scanf("%s%lld", ch, &t);
    43         if(ch[0] == 'I') {
    44             t = (t + lst) % mod;
    45             x = ++p; v = t;
    46             add(1, 1, m);
    47         } else {
    48             if(t == 0) {
    49                 printf("0
    ");
    50                 continue;
    51             }
    52             x = p - t + 1;
    53             y = p;
    54             lst = ask(1, 1, m);
    55             printf("%lld
    ", lst);
    56         }
    57     }
    58 }
    59 
    60 int main() {
    61     freopen("test.in", "r", stdin);
    62     //freopen("test.out", "w", stdout);
    63     solve();
    64     return 0;
    65 }
    View Code

    4. 逆序对,现在有1-n,一共n个数, 求逆序对的个数为m的排列的个数。1 <= n,m <= 1000.

    枚举,数个数,贪心的方式是不行的,那就是dp了。

    枚举最大的一个数,看如何进行转移。dp[i][j] 代表长度为i, 逆序对的个数为j的个数。考虑从dp[i-1]转移过来,增加的逆序对的个数,就很容易写出来转移方程。

    写出来之后,发现时间复杂度是n^3的,不满足要求, 然后用前缀和维护一下,使得0(1)的求取区间的和。使得复杂度降为n^2.

     1 #include<bits/stdc++.h>
     2 #define pb push_back
     3 typedef long long ll;
     4 using namespace std;
     5 typedef pair<int, int> pii;
     6 const int maxn = 1e3 + 10;
     7 const int mod = 10000;
     8 int n, k;
     9 int dp[maxn][maxn];
    10 int s[maxn][maxn];
    11 void solve() {
    12     cin >> n >> k;
    13 
    14     for (int i = 1; i <= n; i++) {
    15         dp[i][0] = 1;
    16         s[i][0] = 1;
    17         for (int j = 1; j <= k; j++) {
    18             dp[i][j] = s[i - 1][j];
    19             if(j - i >= 0)
    20                 dp[i][j] = (dp[i][j] - s[i - 1][j - i] + mod) % mod;
    21             s[i][j] = (s[i][j - 1] + dp[i][j]) % mod;
    22             //cout << i << " " << j << " " << dp[i][j] << endl;
    23         }
    24 
    25     }
    26     cout << dp[n][k] << endl;
    27 
    28 }
    29 
    30 int main() {
    31     freopen("test.in", "r", stdin);
    32     //freopen("test.out", "w", stdout);
    33     ios::sync_with_stdio(0);
    34     cin.tie(0); cout.tie(0);
    35 
    36     solve();
    37     return 0;
    38 }
    View Code
  • 相关阅读:
    低落
    栗子
    Wireless Password HDU
    考研路茫茫——单词情结 HDU
    DNA Sequence POJ
    HDU 6138 Fleet of the Eternal Throne 多校#8 AC自动机
    Rikka with Candies HDU
    Wavel Sequence HDU
    Counting Divisors HDU
    Codeforces Round #424 E. Cards Sorting 线段树/数据结构瞎搞/模拟
  • 原文地址:https://www.cnblogs.com/y119777/p/6930627.html
Copyright © 2011-2022 走看看