A题,水题,只要暴力即可,要注意的是题意要理解清楚。

  B题,枚举每一个x作为矩形的右边,那么其中的贡献是可以用等差数列累和公式计算的,最后对所有可能的答案取一个max即可。该题很友好,使用floor没有被卡精度= =。

  C题,由于题目是保证了一定能够使得满足要求,那么如果remove的时候这个栈不是递减的只需要给它排序一下即可。实际上并不需要对其这样模拟(也不可以这样模拟),具体做法见代码:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N = 3e5 + 10;
 4 typedef long long ll;
 5 
 6 int n;
 7 char s[100];
 8 vector<int> v;
 9 
10 int main()
11 {
12     cin >> n;
13     stack<int> S;
14     int ans = 0;
15     int now = 0;
16     for(int i=1;i<=2*n;i++)
17     {
18         scanf("%s",s);
19         if(strcmp(s, "add") == 0)
20         {
21             int x;
22             scanf("%d",&x);
23             S.push(x);
24         }
25         else
26         {
27             now++;
28             if(!S.empty())
29             {
30                 if(S.top() != now)
31                 {
32                     ans++;
33                     while(!S.empty()) S.pop();
34                 }
35                 else S.pop();
36             }
37         }
38     }
39     cout << ans << endl;
40     return 0;
41 }
C

  

  D题,最短路问题。采用如下的建边方式:

  但是如果n方建边一定会爆内存,因此不建边,直接for一遍更新dis数组即可。代码如下:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N = 1e4 + 10;
 4 typedef long long ll;
 5 typedef pair<int,int> pii;
 6 const int inf = 0x3f3f3f3f;
 7 
 8 int n,m,k;
 9 pii p[N];
10 int d[N], inq[N];
11 int s, ed;
12 int spfa()
13 {
14     memset(d, inf, sizeof d);
15     d[s] = 0;
16     inq[s] = 1;
17     queue<int> Q;
18     Q.push(s);
19     while(!Q.empty())
20     {
21         int u = Q.front(); Q.pop();
22         inq[u] = 0;
23         for(int i=1;i<=k;i++)
24         {
25             if(i != u)
26             {
27                 int val = inf;
28                 int dx = abs(p[u].first - p[i].first);
29                 int dy = abs(p[u].second - p[i].second);
30                 if(dx + dy == 1) val = 0;
31                 else if(dx <= 2 || dy <= 2) val = 1;
32                 if(d[i] > d[u] + val)
33                 {
34                     d[i] = d[u] + val;
35                     if(inq[i] == 0)
36                     {
37                         inq[i] = 1;
38                         Q.push(i);
39                     }
40                 }
41             }
42         }
43     }
44     return d[ed] == inf ? -1 : d[k];
45 }
46 
47 int main()
48 {
49     cin >> n >> m >> k;
50     bool ok = 0;
51     for(int i=1;i<=k;i++)
52     {
53         int x, y;
54         scanf("%d%d",&x,&y);
55         p[i] = pii(x, y);
56         if(x == n && y == m) ok = true, ed = i;
57         if(x == 1 && y == 1) s = i;
58     }
59     if(!ok)
60     {
61         k++;
62         p[k] = pii(n + 1, m + 1);
63         ed = k;
64     }
65     cout << spfa() << endl;
66     return 0;
67 }
D

 

  E题,dp转移方程很容易想到,同时由于ci很小,k很大,考虑使用矩阵快速幂处理递推。代码如下:

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 typedef long long ll;
  4 typedef pair<int,int> pii;
  5 const int mod = 1e9 + 7;
  6 
  7 void add(int &a,int b)
  8 {
  9     a += b;
 10     if(a < 0) a += mod;
 11     a %= mod;
 12 }
 13 
 14 struct matrix
 15 {
 16     int e[16+5][16+5],n,m;
 17     matrix() {}
 18     matrix(int _n,int _m): n(_n),m(_m) {memset(e,0,sizeof(e));}
 19     matrix operator * (const matrix &temp)const
 20     {
 21         matrix ret = matrix(n,temp.m);
 22         for(int i=1;i<=ret.n;i++)
 23         {
 24             for(int j=1;j<=ret.m;j++)
 25             {
 26                 for(int k=1;k<=m;k++)
 27                 {
 28                     add(ret.e[i][j],1LL*e[i][k]*temp.e[k][j]%mod);
 29                 }
 30             }
 31         }
 32         return ret;
 33     }
 34     matrix operator + (const matrix &temp)const
 35     {
 36         matrix ret = matrix(n,m);
 37         for(int i=1;i<=n;i++)
 38         {
 39             for(int j=1;j<=m;j++)
 40             {
 41                 add(ret.e[i][j],(e[i][j]+temp.e[i][j])%mod);
 42             }
 43         }
 44         return ret;
 45     }
 46     void getE()
 47     {
 48         for(int i=1;i<=n;i++)
 49         {
 50             for(int j=1;j<=m;j++)
 51             {
 52                 e[i][j] = i==j?1:0;
 53             }
 54         }
 55     }
 56 };
 57 
 58 matrix qpow(matrix temp,ll x)
 59 {
 60     int sz = temp.n;
 61     matrix base = matrix(sz,sz);
 62     base.getE();
 63     while(x)
 64     {
 65         if(x & 1) base = base * temp;
 66         x >>= 1;
 67         temp = temp * temp;
 68     }
 69     return base;
 70 }
 71 
 72 void print(matrix p)
 73 {
 74     int n = p.n;
 75     int m = p.m;
 76     for(int i=1;i<=n;i++)
 77     {
 78         for(int j=1;j<=m;j++)
 79         {
 80             printf("%d ",p.e[i][j]);
 81         }
 82         cout << endl;
 83     }
 84 }
 85 
 86 int main()
 87 {
 88     int n;
 89     ll k;
 90     cin >> n >> k;
 91     matrix ans = matrix(16, 16);
 92     ans.e[1][1] = 1;
 93     for(int i=1;i<=n;i++)
 94     {
 95         ll x, y;
 96         int h;
 97         scanf("%I64d%I64d%d",&x,&y,&h);
 98         if(x >= k) continue;
 99         h++;
100         matrix temp = matrix(h, h);
101         for(int i=1;i<=h;i++)
102         {
103             temp.e[i][i] = 1;
104             for(int j=-1;j<=1;j++)
105             {
106                 if(i+j>=1) temp.e[i+j][i] = 1;
107                 if(i+j<=h) temp.e[i+j][i] = 1;
108             }
109         }
110         ans = ans * qpow(temp, min(y, k) - x);
111     }
112     cout << ans.e[1][1] << endl;
113     return 0;
114 }
E