【CF】283D Tennis Game

枚举t加二分判断当前t是否可行,同时求出s。
注意不能说|a[n]| <= |3-a[n]|就证明无解,开始就是wa在这儿了。
可以简单想象成每当a[n]赢的时候,两人都打的难解难分(仅多赢一轮);而每当a[n]输的时候,一轮都没赢。
在这个前提下,显然存在|a[n]| <= |3-a[n]|。

  1 /* 283D */
  2 #include <iostream>
  3 #include <string>
  4 #include <map>
  5 #include <queue>
  6 #include <set>
  7 #include <stack>
  8 #include <vector>
  9 #include <deque>
 10 #include <algorithm>
 11 #include <cstdio>
 12 #include <cmath>
 13 #include <ctime>
 14 #include <cstring>
 15 #include <climits>
 16 #include <cctype>
 17 #include <cassert>
 18 #include <functional>
 19 #include <iterator>
 20 #include <iomanip>
 21 using namespace std;
 22 //#pragma comment(linker,"/STACK:102400000,1024000")
 23 
 24 #define sti                set<int>
 25 #define stpii            set<pair<int, int> >
 26 #define mpii            map<int,int>
 27 #define vi                vector<int>
 28 #define pii                pair<int,int>
 29 #define vpii            vector<pair<int,int> >
 30 #define rep(i, a, n)     for (int i=a;i<n;++i)
 31 #define per(i, a, n)     for (int i=n-1;i>=a;--i)
 32 #define clr                clear
 33 #define pb                 push_back
 34 #define mp                 make_pair
 35 #define fir                first
 36 #define sec                second
 37 #define all(x)             (x).begin(),(x).end()
 38 #define SZ(x)             ((int)(x).size())
 39 #define lson            l, mid, rt<<1
 40 #define rson            mid+1, r, rt<<1|1
 41 
 42 const int maxn = 1e5+5;
 43 int a[maxn];
 44 int cnt[3][maxn];
 45 int n;
 46 int id;
 47 
 48 int calc(int t) {
 49     int i, j, p, q;
 50     int c[3];
 51     int b[3];
 52     
 53     b[1] = b[2] = 0;
 54     c[1] = c[2] = 0;
 55     p = 0;
 56     while (1) {
 57         i = lower_bound(cnt[1]+p, cnt[1]+1+n, c[1]+t) - (cnt[1]);
 58         j = lower_bound(cnt[2]+p, cnt[2]+1+n, c[2]+t) - (cnt[2]);
 59         if (cnt[1][i]-c[1]!=t && cnt[2][j]-c[2]!=t)
 60             return 0;
 61         if (i < j) {
 62             // 1 win
 63             q = 1;
 64             ++b[1];
 65             p = i;
 66         } else {
 67             q = 2;
 68             ++b[2];
 69             p = j;
 70         }
 71         c[1] = cnt[1][p];
 72         c[2] = cnt[2][p];
 73         if (p >= n)
 74             break;
 75     }
 76     
 77     if (p != n)
 78         return 0;
 79     
 80     int id_ = 3 - id;
 81     if (b[id_]>=b[id] || q!=id)
 82         return 0;
 83     return b[id];
 84 }
 85     
 86 int main() {
 87     ios::sync_with_stdio(false);
 88     #ifndef ONLINE_JUDGE
 89         freopen("data.in", "r", stdin);
 90         freopen("data.out", "w", stdout);
 91     #endif
 92     
 93     int c[3];
 94     
 95     scanf("%d", &n);
 96     c[1] = c[2] = 0;
 97     rep(i, 1, n+1) {
 98         scanf("%d", &a[i]);
 99         ++c[a[i]];
100         cnt[a[i]][i] = cnt[a[i]][i-1] + 1;
101         cnt[3-a[i]][i] = cnt[3-a[i]][i-1];
102     }
103     cnt[1][n+1] = cnt[2][n+1] = INT_MAX;
104     
105     id = a[n];
106     int an = c[id], bn = c[1]+c[2]-an;
107     
108     // if (an <= bn) {
109         // puts("0");
110         // return 0;
111     // }
112     
113     int i, j;
114     vpii ans;
115     
116     for (i=1; i<=n; ++i) {
117         j = calc(i);
118         if (j)
119             ans.pb(mp(j, i));
120     }
121     
122     sort(all(ans));
123     
124     n = SZ(ans);
125     printf("%d
", n);
126     rep(i, 0, n) {
127         printf("%d %d
", ans[i].fir, ans[i].sec);
128     }
129     
130     #ifndef ONLINE_JUDGE
131         printf("time = %d.
", (int)clock());
132     #endif
133     
134     return 0;
135 }
原文地址:https://www.cnblogs.com/bombe1013/p/4617373.html