Vasya has recently got a job as a cashier at a local store. His day at work is L L L minutes long. Vasya has already memorized n n n regular customers, the i − t h i-th i−th of which comes after t i t_i ti minutes after the beginning of the day, and his service consumes l i l_i li minutes. It is guaranteed that no customer will arrive while Vasya is servicing another customer.
Vasya is a bit lazy, so he likes taking smoke breaks for a a a minutes each. Those breaks may go one after another, but Vasya must be present at work during all the time periods he must serve regular customers, otherwise one of them may alert his boss. What is the maximum number of breaks Vasya can take during the day?
The first line contains three integers n n n, L L L and a a a ( 0 ≤ n ≤ 1 0 5 0≤n≤10^5 0≤n≤105, 1 ≤ L ≤ 1 0 9 1≤L≤10^9 1≤L≤109, 1 ≤ a ≤ L 1≤a≤L 1≤a≤L).
The i − t h i-th i−th of the next n n n lines contains two integers t i t_i ti and l i l_i li ( 0 ≤ t i ≤ L − 1 0≤t_i≤L−1 0≤ti≤L−1, 1 ≤ l i ≤ L 1≤l_i≤L 1≤li≤L). It is guaranteed that t i + l i ≤ t i + 1 t_i+l_i≤t_{i+1} ti+li≤ti+1 and t n + l n ≤ L t_n+l_n≤L tn+ln≤L.
Output one integer — the maximum number of breaks.
2 11 3
0 1
1 1
3
0 5 2
2
1 3 2
1 2
0
In the first sample Vasya can take 3 3 3 breaks starting after 2 2 2, 5 5 5 and 8 8 8 minutes after the beginning of the day.
In the second sample Vasya can take 2 2 2 breaks starting after 0 0 0 and 2 2 2 minutes after the beginning of the day.
In the third sample Vasya can’t take any breaks.
加一个 0 0 0, 加一个 L L L, 然后间隔除以 a a a下取整就好了。
代码如下:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define register
#define IN inline
#define R register
#define W while
#define gc getchar()
#define ll long long
#define db double
#define lowbit(i) ((i) & (-(i)))
const db PI = std::acos(-1.0);
int seq[300050];
int main(void)
{
int a, b, cnt = 0, ans = 0;
int n, l, k;
scanf("%d%d%d", &n, &l, &k);
for (R int i = 1; i <= n; ++i)
{
scanf("%d%d", &a, &b);
seq[++cnt] = a, seq[++cnt] = a + b;
}
seq[++cnt] = 0, seq[++cnt] = l;
std::sort(seq + 1, seq + 1 + cnt);
for (R int i = 1; i < cnt; i += 2)
ans += (seq[i + 1] - seq[i]) / k;
printf("%d", ans);
}
Student Andrey has been skipping physical education lessons for the whole term, and now he must somehow get a passing grade on this subject. Obviously, it is impossible to do this by legal means, but Andrey doesn’t give up. Having obtained an empty certificate from a local hospital, he is going to use his knowledge of local doctor’s handwriting to make a counterfeit certificate of illness. However, after writing most of the certificate, Andrey suddenly discovered that doctor’s signature is impossible to forge. Or is it?
For simplicity, the signature is represented as an n × m n×m n×m grid, where every cell is either filled with ink or empty. Andrey’s pen can fill a 3 × 3 3×3 3×3square without its central cell if it is completely contained inside the grid, as shown below.
xxx
x.x
xxx
Determine whether is it possible to forge the signature on an empty n × m n×m n×m grid.
The first line of input contains two integers n n n and m m m ( 3 ≤ n , m ≤ 1000 3≤n,m≤1000 3≤n,m≤1000).
Then n n n lines follow, each contains m m m characters. Each of the characters is either.
, representing an empty cell, or #
, representing an ink filled cell.
If Andrey can forge the signature, output YES
. Otherwise output NO
.
You can print each letter in any case (upper or lower).
3 3
###
#.#
###
YES
3 3
###
###
###
NO
4 3
###
###
###
###
YES
5 7
.......
.#####.
.#.#.#.
.#####.
.......
YES
一开始想这个图形是不是有什么特殊性质, 然后忽然发现 n , m ≤ 1000 n,m\leq 1000 n,m≤1000…
直接枚举每个格子看作为左上角是不是可以涂色, 如果可以涂就涂一下, 最后看有没有没涂到的地方就好。
代码如下:(略宽…)
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define register
#define IN inline
#define R register
#define W while
#define gc getchar()
#define ll long long
#define db double
#define lowbit(i) ((i) & (-(i)))
const db PI = std::acos(-1.0);
#define MX 1005
char mp[MX][MX];
int tim[MX][MX];
int n, m;
IN bool check(R int x, R int y)
{
return ((mp[x][y] == '#') & (mp[x][y + 1] == '#') & (mp[x][y + 2] == '#') & (mp[x + 1][y] == '#') & (mp[x + 1][y + 2] == '#') & (mp[x + 2][y] == '#') & (mp[x + 2][y + 1] == '#') & (mp[x + 2][y + 2] == '#'));
}
IN void work(R int x, R int y)
{
tim[x][y]++;
tim[x][y + 1]++;
tim[x][y + 2]++;
tim[x + 1][y]++;
tim[x + 1][y + 2]++;
tim[x + 2][y]++;
tim[x + 2][y + 1]++;
tim[x + 2][y + 2]++;
}
IN void fil(R int x, R int y)
{
if(x + 2 > n || y + 2 > m) return;
if(check(x, y)) work(x, y);
}
int main(void)
{
scanf("%d%d", &n, &m);
for (R int i = 1; i <= n; ++i)
scanf("%s", mp[i] + 1);
for (R int i = 1; i <= n; ++i)
for (R int j = 1; j <= m; ++j)
{
if(mp[i][j] == '#') fil(i, j);
}
for (R int i = 1; i <= n; ++i)
for (R int j = 1; j <= m; ++j) if(mp[i][j] == '#' && (!tim[i][j])) return puts("NO"), 0;
puts("YES");
}
Let’s call the following process a transformation of a sequence of length n n n.
If the sequence is empty, the process ends. Otherwise, append the greatest common divisor ( G C D GCD GCD) of all the elements of the sequence to the result and remove one arbitrary element from the sequence. Thus, when the process ends, we have a sequence of n n n integers: the greatest common divisors of all the elements in the sequence before each deletion.
You are given an integer sequence 1 , 2 , … , n 1,2,…,n 1,2,…,n. Find the lexicographically maximum result of its transformation.
A sequence a 1 , a 2 , … , a n a_1,a_2,…,a_n a1,a2,…,anis lexicographically larger than a sequence b 1 , b 2 , … , b n b_1,b_2,…,b_n b1,b2,…,bn, if there is an index i i i such that a j = b j a_j=b_j aj=bj for all j < i j<i j<i, and a i > b i a_i>b_i ai>bi.
The first and only line of input contains one integer n n n ( 1 ≤ n ≤ 1 0 6 1≤n≤10^6 1≤n≤106).
Output n n n integers — the lexicographically maximum result of the transformation.
3
1 1 3
2
1 2
1
1
看起来很水的样例其实好心地提醒了我们…
首先我们肯定会先将所有奇数删掉, 这样就可以提出一个 2 2 2, 而如果要提出其他的约数肯定(???)要多删一些。
然后我们发现这样可以递归处理提出 2 2 2之后的那个数列。
但这样就是对的吗? 我们可以看下样例 1 1 1, 发现 3 3 3的时候需要特判。
这样就能 A A A了。
代码如下:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define register
#define IN inline
#define R register
#define W while
#define gc getchar()
#define ll long long
#define db double
#define lowbit(i) ((i) & (-(i)))
#define MX 1000050
const db PI = std::acos(-1.0);
int n;
void solve(R int len, R int mul)
{
if(len == 1) return printf("%d ", (int)pow(2, mul)), void();
if(len == 3) return printf("%d %d %d", (int)pow(2, mul), (int)pow(2, mul), (int)pow(2, mul) * 3), void();
int num = (len + 1) >> 1;
int ans = pow(2, mul);
for (R int i = 1; i <= num; ++i) printf("%d ", ans);
solve(len >> 1, mul + 1);
}
int main(void)
{
scanf("%d", &n);
solve(n, 0);
}
There is a forest that we model as a plane and live n n n rare animals. Animal number i i i has its lair in the point ( x i , y i ) (x_i,y_i) (xi,yi). In order to protect them, a decision to build a nature reserve has been made.
The reserve must have a form of a circle containing all lairs. There is also a straight river flowing through the forest. All animals drink from this river, therefore it must have at least one common point with the reserve. On the other hand, ships constantly sail along the river, so the reserve must not have more than one common point with the river.
For convenience, scientists have made a transformation of coordinates so that the river is defined by y = 0 y=0 y=0. Check whether it is possible to build a reserve, and if possible, find the minimum possible radius of such a reserve.
The first line contains one integer n n n ( 1 ≤ n ≤ 1 0 5 1≤n≤10^5 1≤n≤105) — the number of animals.
Each of the next n n n lines contains two integers x i x_i xi, y i y_i yi ( − 1 0 7 ≤ x i , y i ≤ 1 0 7 −10^7≤x_i,y_i≤10^7 −107≤xi,yi≤107) — the coordinates of the i − t h i-th i−th animal’s lair. It is guaranteed that y i ≠ 0 y_i≠0 yi̸=0. No two lairs coincide.
If the reserve cannot be built, print − 1 −1 −1. Otherwise print the minimum radius. Your answer will be accepted if absolute or relative error does not exceed 1 0 − 6 10^{−6} 10−6.
Formally, let your answer be a a a, and the jury’s answer be b b b. Your answer is considered correct if ∣ a − b ∣ m a x ( 1 , ∣ b ∣ ) \frac{|a-b|}{max(1,|b|)} max(1,∣b∣)∣a−b∣.
1
0 1
0.5
3
0 1
0 2
0 -3
-1
2
0 1
1 1
0.625
比赛的时候一直去想凸包了, 然后发现好像咋搞都不可能小于 O ( N 2 ) O(N^2) O(N2)的样子。
其实还有一个很好的条件没有用: 切 y = 0 y=0 y=0这条直线。
那么如果半径是 R \mathcal{R} R, 圆心可能的位置也就在一条平行于 y y y轴的直线上面。
那么二分这个半径, 对于一个点 ( x , y ) (x,y) (x,y)在这个直线上有一段区间 [ l , r ] [l,r] [l,r], 在这段区间内圆心到这个点的距离是 ≤ R \leq \mathcal{R} ≤R的,如果有解即所有区间有公共部分。
精度十分爆炸, 用 l o n g d o u b l e long\ double long double。
代码如下:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define register
#define IN inline
#define R register
#define W while
#define gc getchar()
#define ll long long
#define db long double
#define lowbit(i) ((i) & (-(i)))
#define MX 100050
#define EPS 1e-8
using std::cin; using std::cout;
template <class T>
IN T sqr(const T &x) {return x * x;}
const db PI = std::acos(-1.0);
struct pt {db x, y;} dat[MX];
IN pt operator + (const pt &x, const pt &y) {return {x.x + y.x, x.y + y.y};}
IN pt operator - (const pt &x, const pt &y) {return {x.x - y.x, x.y - y.y};}
IN db operator * (const pt &x, const pt &y) {return x.x * y.y - x.y * y.x;}
int n, neg, pos;
IN bool check(db r)
{
db lef = -2e16, rig = 2e16, lb, rb, del;
for (R int i = 1; i <= n; ++i)
{
if(fabs(r - dat[i].y) > r) return false;
del = std::sqrt(sqr(r) - sqr(r - dat[i].y));
lb = dat[i].x - del, rb = dat[i].x + del;
lef = std::max(lef, lb), rig = std::min(rig, rb);
if(lef > rig) return false;
}
return true;
}
int main(void)
{
std::ios_base::sync_with_stdio(false);
cin.tie(0);
cin >> n;
for (R int i = 1; i <= n; ++i)
{
cin >> dat[i].x >> dat[i].y;
if(dat[i].y < 0) ++neg;
else ++pos;
}
if(neg && pos) return puts("-1"), 0;
if(neg) for (R int i = 1; i <= n; ++i) dat[i].y = -dat[i].y;
db lef = 0, rig = 1e16, mid;
int cnt = 250;
W (cnt--)
{
mid = (lef + rig) / 2.0000000000;
if(check(mid)) rig = mid;
else lef = mid;
}
cout.precision(16);
cout << std::fixed << rig;
}
You are given a rooted tree on n n n vertices, its root is the vertex number 1 1 1. The i − t h i-th i−th vertex contains a number w i w_i wi. Split it into the minimum possible number of vertical paths in such a way that each path contains no more than L L L vertices and the sum of integers w i w_i wi on each path does not exceed S S S. Each vertex should belong to exactly one path.
The first line contains three integers n n n, L L L, S S S ( 1 ≤ n ≤ 1 0 5 1≤n≤10^5 1≤n≤105, 1 ≤ L ≤ 1 0 5 1≤L≤10^5 1≤L≤105, 1 ≤ S ≤ 1 0 18 1≤S≤10^{18} 1≤S≤1018) — the number of vertices, the maximum number of vertices in one path and the maximum sum in one path.
The second line contains nn integers w 1 , w 2 , … , w n w_1,w_2,…,w_n w1,w2,…,wn ( 1 ≤ w i ≤ 1 0 9 1≤w_i≤10^9 1≤wi≤109) — the numbers in the vertices of the tree.
The third line contains n − 1 n−1 n−1 integers p 2 , … , p n p_2,…,p_n p2,…,pn ( 1 ≤ p i < i 1≤p_i<i 1≤pi<i), where p i p_i pi is the parent of the i − t h i-th i−th vertex in the tree.
Output one number — the minimum number of vertical paths. If it is impossible to split the tree, output − 1 −1 −1.
3 1 3
1 2 3
1 1
3
3 3 6
1 2 3
1 1
2
1 1 10000
10001
-1
比赛的时候知道要贪心取向上延伸最远的, 但不知道怎么维护…
WOC, 这TM不就一个倍增吗??
下次比赛的时候一定要先睡一觉…
代码如下:
#include
#include
#include
#include
#include
#include
#define R register
#define IN inline
#define W while
#define gc getchar()
#define MX 100050
#define ll long long
int top[MX], dep[MX], fat[MX][18], to[MX], head[MX], val[MX];
ll pre[MX], mx;
int dot, lim, ans, cnt, lg;
struct Edge {int to, nex;} edge[MX << 1];
IN void add(R int from, R int to) {edge[++cnt] = {to, head[from]}, head[from] = cnt;}
void DFS(R int now)
{
pre[now] = pre[fat[now][0]] + val[now];
to[now] = now;
R int lm = lim;
for (R int i = 1; i < lg; ++i) fat[now][i] = fat[fat[now][i - 1]][i - 1];
for (R int i = lg - 1; ~i; --i)
{
if((!fat[to[now]][i]) || (1 << i) > lm) continue;
if(pre[now] - pre[fat[to[now]][i]] + val[fat[to[now]][i]] <= mx)
lm -= (1 << i), to[now] = fat[to[now]][i];
}
for (R int i = head[now]; i; i = edge[i].nex)
{
dep[edge[i].to] = dep[now] + 1;
fat[edge[i].to][0] = now;
DFS(edge[i].to);
}
}
int solve(R int now)
{
int ret = 0, best = -1;
for (R int i = head[now]; i; i = edge[i].nex)
{
ret += solve(edge[i].to);
if(top[edge[i].to] == edge[i].to) continue;
if(best == -1 || dep[top[edge[i].to]] < dep[best]) best = top[edge[i].to];
}
if(best == -1) ++ret, best = to[now];
top[now] = best;
return ret;
}
int main(void)
{
int a;
scanf("%d%d%I64d", &dot, &lim, &mx); --lim; lg = log2(dot) + 1;
for (R int i = 1; i <= dot; ++i) {scanf("%d", &val[i]); if(val[i] > mx) return puts("-1"), 0;}
for (R int i = 2; i <= dot; ++i) scanf("%d", &a), add(a, i);
DFS(1); printf("%d", solve(1));
}