A. Stickers and Toys
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
Your favorite shop sells ?n Kinder Surprise chocolate eggs. You know that exactly ?s stickers and exactly ?t toys are placed in ?n eggs in total.
Each Kinder Surprise can be one of three types:
- it can contain a single sticker and no toy;
- it can contain a single toy and no sticker;
- it can contain both a single sticker and a single toy.
But you don't know which type a particular Kinder Surprise has. All eggs look identical and indistinguishable from each other.
What is the minimum number of Kinder Surprise Eggs you have to buy to be sure that, whichever types they are, you'll obtain at least one sticker and at least one toy?
Note that you do not open the eggs in the purchasing process, that is, you just buy some number of eggs. It's guaranteed that the answer always exists.
Input
The first line contains the single integer ?T (1≤?≤1001≤T≤100) — the number of queries.
Next ?T lines contain three integers ?n, ?s and ?t each (1≤?≤1091≤n≤109, 1≤?,?≤?1≤s,t≤n, ?+?≥?s+t≥n) — the number of eggs, stickers and toys.
All queries are independent.
Output
Print ?T integers (one number per query) — the minimum number of Kinder Surprise Eggs you have to buy to be sure that, whichever types they are, you'll obtain at least one sticker and one toy
就是问在已知物品总数和toy数还有sticker数的时候,求各要一个时候的最少购买的物品总数。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
int N, S, T;
int main()
{
int Cas; scanf("%d", &Cas);
while(Cas--)
{
scanf("%d%d%d", &N, &S, &T);
printf("%d\n", max(N - S, N - T) + 1);
}
return 0;
}
B. Letters Shop
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
The letters shop showcase is a string ?s, consisting of ?n lowercase Latin letters. As the name tells, letters are sold in the shop.
Letters are sold one by one from the leftmost to the rightmost. Any customer can only buy some prefix of letters from the string ?s.
There are ?m friends, the ?i-th of them is named ??ti. Each of them is planning to estimate the following value: how many letters (the length of the shortest prefix) would s/he need to buy if s/he wanted to construct her/his name of bought letters. The name can be constructed if each letter is presented in the equal or greater amount.
- For example, for ?s="arrayhead" and ??ti="arya" 55 letters have to be bought ("arrayhead").
- For example, for ?s="arrayhead" and ??ti="harry" 66 letters have to be bought ("arrayhead").
- For example, for ?s="arrayhead" and ??ti="ray" 55 letters have to be bought ("arrayhead").
- For example, for ?s="arrayhead" and ??ti="r" 22 letters have to be bought ("arrayhead").
- For example, for ?s="arrayhead" and ??ti="areahydra" all 99 letters have to be bought ("arrayhead").
It is guaranteed that every friend can construct her/his name using the letters from the string ?s.
Note that the values for friends are independent, friends are only estimating them but not actually buying the letters.
Input
The first line contains one integer ?n (1≤?≤2⋅1051≤n≤2⋅105) — the length of showcase string ?s.
The second line contains string ?s, consisting of exactly ?n lowercase Latin letters.
The third line contains one integer ?m (1≤?≤5⋅1041≤m≤5⋅104) — the number of friends.
The ?i-th of the next ?m lines contains ??ti (1≤|??|≤2⋅1051≤|ti|≤2⋅105) — the name of the ?i-th friend.
It is guaranteed that ∑?=1?|??|≤2⋅105∑i=1m|ti|≤2⋅105.
Output
For each friend print the length of the shortest prefix of letters from ?s s/he would need to buy to be able to construct her/his name of them. The name can be constructed if each letter is presented in the equal or greater amount.
It is guaranteed that every friend can construct her/his name using the letters from the string ?s.
这题给我的第一印象就是需要我们去手写一个二分了。还不需要排序,因为是给好的顺序。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxN = 2e5 + 7;
struct node
{
int a[26], id;
node() { memset(a, 0, sizeof(a)); id = 0; }
node(int x[]) { for(int i=0; i<26; i++) a[i] = x[i]; }
friend bool operator < (node e1, node e2)
{
bool flag = true;
for(int i=0; i<26; i++) if(e1.a[i] > e2.a[i]) { flag = false; break; }
return flag;
}
}t[maxN];
bool cmp(node e1, node e2)
{
bool flag = true;
for(int i=0; i<26; i++) if(e1.a[i] > e2.a[i]) { flag = false; break; }
return flag;
}
int N, M, a[26], tmp[26];
char s[maxN],q[maxN];
int erfen()
{
int L = 1, R = N, mid = 0, ans = N;
while(L <= R)
{
mid = (L + R)>>1;
bool flag = true;
for(int i=0; i<26; i++) if(t[mid].a[i] < tmp[i]) { flag = false; break; }
if(flag)
{
R = mid - 1;
ans = mid;
}
else L = mid + 1;
}
return ans;
}
int main()
{
scanf("%d", &N);
scanf("%s", s + 1);
memset(a, 0, sizeof(a));
for(int i=1; i<=N; i++)
{
t[i] = t[i-1];
++t[i].id;
t[i].a[s[i] - 'a']++;
}
scanf("%d", &M);
while(M--)
{
scanf("%s", q + 1);
memset(tmp, 0, sizeof(tmp));
int len = (int)strlen(q + 1);
for(int i=1; i<=len; i++) tmp[q[i] - 'a']++;
printf("%d\n", erfen());
}
return 0;
}
C. Vasya And Array
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output
Vasya has an array ?1,?2,…,??a1,a2,…,an.
You don't know this array, but he told you ?m facts about this array. The ?i-th fact is a triple of numbers ??ti, ??li and ??ri (0≤??≤1,1≤??<??≤?0≤ti≤1,1≤li<ri≤n) and it means:
- if ??=1ti=1 then subbarray ???,???+1,…,???ali,ali+1,…,ari is sorted in non-decreasing order;
- if ??=0ti=0 then subbarray ???,???+1,…,???ali,ali+1,…,ari is not sorted in non-decreasing order. A subarray is not sorted if there is at least one pair of consecutive elements in this subarray such that the former is greater than the latter.
For example if ?=[2,1,1,3,2]a=[2,1,1,3,2] then he could give you three facts: ?1=1,?1=2,?1=4t1=1,l1=2,r1=4 (the subarray [?2,?3,?4]=[1,1,3][a2,a3,a4]=[1,1,3] is sorted), ?2=0,?2=4,?2=5t2=0,l2=4,r2=5 (the subarray [?4,?5]=[3,2][a4,a5]=[3,2] is not sorted), and ?3=0,?3=3,?3=5t3=0,l3=3,r3=5 (the subarray [?3,?5]=[1,3,2][a3,a5]=[1,3,2] is not sorted).
You don't know the array ?a. Find any array which satisfies all the given facts.
Input
The first line contains two integers ?n and ?m (2≤?≤1000,1≤?≤10002≤n≤1000,1≤m≤1000).
Each of the next ?m lines contains three integers ??ti, ??li and ??ri (0≤??≤1,1≤??<??≤?0≤ti≤1,1≤li<ri≤n).
If ??=1ti=1 then subbarray ???,???+1,…,???ali,ali+1,…,ari is sorted. Otherwise (if ??=0ti=0) subbarray ???,???+1,…,???ali,ali+1,…,ari is not sorted.
Output
If there is no array that satisfies these facts in only line print NO (in any letter case).
If there is a solution, print YES (in any letter case). In second line print ?n integers ?1,?2,…,??a1,a2,…,an (1≤??≤1091≤ai≤109) — the array ?a, satisfying all the given facts. If there are multiple satisfying arrays you can print any of them.
这题是个构造问题,发现N不是很大,说明我们可以去走一个O(N * M)的时间来做,然后直接这样,如果要求是1的话,把这个区间直接弄成相等,要是这个区间不做要求,就按连续下降来写。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxN = 1e3 + 7;
int N, M, tot, lazy[maxN], ans[maxN];
struct node
{
int l, r;
node(int a=0, int b=0):l(a), r(b) {}
}q[maxN];
int main()
{
tot = 0;
scanf("%d%d", &N, &M);
for(int i=1, op, l, r; i<=M; i++)
{
scanf("%d%d%d", &op, &l, &r);
if(op)
{
for(int i = l + 1; i <= r; i++) lazy[i] = 1;
}
else
{
q[++tot] = node(l, r);
}
}
ans[0] = N + 1;
for(int i=1; i<=N; i++)
{
if(lazy[i]) ans[i] = ans[i-1];
else ans[i] = ans[i-1] - 1;
}
for(int i=1; i<=tot; i++)
{
if(ans[q[i].l] == ans[q[i].r]) { printf("NO\n"); return 0; }
}
printf("YES\n");
for(int i=1; i<=N; i++) printf("%d%c", ans[i], i == N ? '\n' : ' ');
return 0;
}
E. Tree Painting
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
You are given a tree (an undirected connected acyclic graph) consisting of ?n vertices. You are playing a game on this tree.
Initially all vertices are white. On the first turn of the game you choose one vertex and paint it black. Then on each turn you choose a white vertex adjacent (connected by an edge) to any black vertex and paint it black.
Each time when you choose a vertex (even during the first turn), you gain the number of points equal to the size of the connected component consisting only of white vertices that contains the chosen vertex. The game ends when all vertices are painted black.
Let's see the following example:
Vertices 11 and 44 are painted black already. If you choose the vertex 22, you will gain 44 points for the connected component consisting of vertices 2,3,52,3,5 and 66. If you choose the vertex 99, you will gain 33 points for the connected component consisting of vertices 7,87,8 and 99.
Your task is to maximize the number of points you gain.
Input
The first line contains an integer ?n — the number of vertices in the tree (2≤?≤2⋅1052≤n≤2⋅105).
Each of the next ?−1n−1 lines describes an edge of the tree. Edge ?i is denoted by two integers ??ui and ??vi, the indices of vertices it connects (1≤??,??≤?1≤ui,vi≤n, ??≠??ui≠vi).
It is guaranteed that the given edges form a tree.
Output
Print one integer — the maximum number of points you gain if you will play optimally.
这道题挺难的,要推一个换树的根的树形DP的转移方程,结果可以看成S + N - 2 * size[v];S是父亲节点作为根时候的获得的值的大小。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxN = 2e5 + 7;
int N, head[maxN], cnt, siz[maxN];
struct Eddge
{
int nex, to;
Eddge(int a=-1, int b=0):nex(a), to(b) {}
}edge[maxN<<1];
inline void addEddge(int u, int v)
{
edge[cnt] = Eddge(head[u], v);
head[u] = cnt++;
}
inline void _add(int u, int v) { addEddge(u, v); addEddge(v, u); }
ll ans = 0, all = 0;
inline void pre_dfs(int u, int fa)
{
siz[u] = 1;
for(int i=head[u], v; ~i; i=edge[i].nex)
{
v = edge[i].to;
if(v == fa) continue;
pre_dfs(v, u);
siz[u] += siz[v];
}
all += siz[u];
}
inline void dfs(int u, int fa, ll s)
{
if(s > ans) ans = s;
for(int i=head[u], v; ~i; i=edge[i].nex)
{
v = edge[i].to;
if(v == fa) continue;
dfs(v, u, s + N - 2 * siz[v]);
}
}
inline void init()
{
cnt = 0;
memset(head, -1, sizeof(head));
}
int main()
{
scanf("%d", &N);
init();
for(int i=1, u, v; i<N; i++)
{
scanf("%d%d", &u, &v);
_add(u, v);
}
if(N == 2) { printf("3\n"); return 0; }
if(N == 3) { printf("6\n"); return 0; }
pre_dfs(1, 0);
dfs(1, 0, all);
printf("%lld\n", ans);
return 0;
}