CF1136D Nastya Is Buying Lunch

思路:

1. 最终答案不超过能与Nastya“直接交换”的人数。

2. 对于排在j前面的i,如果i和i~j之间(包括j)的每个人都能“直接交换”,j才能前进一步。 

实现:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N = 300005;
 4 int a[N], p[N], cnt[N];
 5 vector<int> v[N];
 6 
 7 int main()
 8 {
 9     int n, m;
10     while (cin >> n >> m)
11     {
12         for (int i = 1; i <= n; i++) v[i].clear();
13         memset(cnt, 0, sizeof cnt);
14         int x, y;
15         for (int i = 1; i <= n; i++) { cin >> a[i]; p[a[i]] = i; }
16         for (int i = 1; i <= m; i++)
17         {
18             cin >> x >> y;
19             v[y].push_back(x);
20         }
21         for (int i = n; i >= 1; i--)
22         {
23             for (int j = 0; j < v[a[i]].size(); j++)
24             {
25                 if (p[v[a[i]][j]] < i) cnt[v[a[i]][j]]++;
26             }
27         }
28         vector<pair<int, int>> t;
29         for (int i = 0; i < v[a[n]].size(); i++)
30         {
31             int to = v[a[n]][i];
32             t.push_back(make_pair(p[to], to));
33         }
34         sort(t.begin(), t.end());
35         int cur = n, ans = 0;
36         for (int i = t.size() - 1; i >= 0; i--)
37         {
38             x = t[i].second;
39             if (cnt[x] == cur - t[i].first)
40             {
41                 ans++; cur--;
42                 for (int j = 0; j < v[x].size(); j++)
43                 {
44                     int to = v[x][j]; cnt[to]--;
45                 }
46             }
47         }
48         cout << ans << endl;
49     }
50     return 0;
51 }
原文地址:https://www.cnblogs.com/wangyiming/p/11017413.html