[BJWC2008]秦腾与教学评估

嘟嘟嘟

二分好题。

怎么二分呢?反正我是没想出来。

看了题解。

因为只有一个为奇数的点,所以对于一个位置x,求出区间[0, x]的教总和,如果为奇数,说明x取大了;否则x取小了(妙啊)。

虽然答案在int内,但是L + R可能会爆int,导致有几个点TLE了,所以还是都开long long 吧。

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<algorithm>
 5 #include<cstring>
 6 #include<cstdlib>
 7 #include<cctype>
 8 #include<vector>
 9 #include<stack>
10 #include<queue>
11 using namespace std;
12 #define enter puts("") 
13 #define space putchar(' ')
14 #define Mem(a, x) memset(a, x, sizeof(a))
15 #define rg register
16 typedef long long ll;
17 typedef double db;
18 const int INF = 0x3f3f3f3f;
19 const db eps = 1e-8;
20 const int maxn = 2e5 + 5;
21 inline ll read()
22 {
23     ll ans = 0;
24     char ch = getchar(), last = ' ';
25     while(!isdigit(ch)) {last = ch; ch = getchar();}
26     while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();}
27     if(last == '-') ans = -ans;
28     return ans;
29 }
30 inline void write(ll x)
31 {
32     if(x < 0) x = -x, putchar('-');
33     if(x >= 10) write(x / 10);
34     putchar(x % 10 + '0');
35 }
36 
37 int n;
38 struct Node
39 {
40     ll s, e, d;
41 }t[maxn];
42 
43 ll calc(ll x)
44 {
45     ll ret = 0;
46     for(int i = 1; i <= n; ++i)
47     {
48         if(t[i].s > x) continue;
49         ret += (min(x, t[i].e) - t[i].s) / t[i].d + 1;
50     }
51     return ret;
52 }
53 
54 int main()
55 {
56     int T = read();
57     while(T--)
58     {
59         n = read(); ll Max = 0;
60         for(int i = 1; i <= n; ++i) t[i].s = read(), t[i].e = read(), t[i].d = read(), Max = max(Max, t[i].e);
61         ll L = 0, R = Max;
62         if(!(calc(R) & 1)) {puts("Poor QIN Teng:( "); continue;}
63         while(L < R)
64         {
65             ll mid = (L + R) >> 1;
66             if(calc(mid) & 1) R = mid;
67             else L = mid + 1;
68         }
69         write(L), space, write(calc(L) - calc(L - 1)), enter;
70     }
71     return 0;
72 }
View Code

猜你喜欢

转载自www.cnblogs.com/mrclr/p/9840466.html
今日推荐