水题。
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<map>
#define xx first
#define yy second
#define LL long long
#define MP make_pair
#define INF 0x3f3f3f3f
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1|1
#define CLR(a, b) memset(a, b, sizeof(a))
using namespace std;
int main()
{
freopen("alex.in", "r", stdin);
freopen("alex.out", "w", stdout);
double n, m;
while(cin >> n >> m)
{
double mxx = 0;
mxx = max(mxx, min(m, n / 3));
mxx = max(mxx, min(n, m / 3));
mxx = max(mxx, min(m / 2, n / 2));
printf("%.3f\n", mxx);
}
return 0;
}
B- Black and White
不知道题意。
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<map>
#define xx first
#define yy second
#define LL long long
#define MP make_pair
#define INF 0x3f3f3f3f
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1|1
#define CLR(a, b) memset(a, b, sizeof(a))
using namespace std;
int main () {
freopen("black.in", "r", stdin);
freopen("black.out", "w", stdout);
int a, b;
while(cin >> a >> b) {
char x = '.';
char y = '@';
if(a < b) {
swap(x, y);
swap(a, b);
}
// printf("duo %c shao %c\n", x, y);
b --;
int dt = (a - b);
a -= dt;
int r = dt * 2 + 1 + a + b;
int c = 2;
printf("%d %d\n", r, c);
printf("%c%c\n", x, x);
for(int i = 0; i < dt; i ++) {
printf("%c%c\n", x, y);
printf("%c%c\n", x, x);
}
while(a || b) {
if(b) printf("%c%c\n", y, y), b --;
if(a) printf("%c%c\n", x, x), a --;
}
}
return 0;
}
C- Concatenation
给两个字符串s1,s2,求s1的前缀和s2的后缀拼接可以有多少种不同的子串。
总数减去s2中的子串可以作为s1子串的个数就好了。这个可以用后缀数组实现。
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<map>
#define xx first
#define yy second
#define LL long long
#define MP make_pair
#define INF 0x3f3f3f3f
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1|1
#define CLR(a, b) memset(a, b, sizeof(a))
using namespace std;
const int maxn = 211111;
char ch1[maxn], ch2[maxn];
struct SuffixArray
{
int r[maxn];
int sa[maxn], rank[maxn], height[maxn];
int t[maxn], t2[maxn], c[maxn], n;
int m;
void init(char* s)
{
n = strlen(s);
for (int i = 0; i < n; i++) r[i] = int(s[i]);
r[n] = 0;
m = 300;
}
int cmp(int *r, int a, int b, int l)
{
return r[a] == r[b] && r[a + l] == r[b + l];
}
void build_sa()
{
int i, k, p, *x = t, *y = t2;
r[n++] = 0;
for (i = 0; i < m; i++) c[i] = 0;
for (i = 0; i < n; i++) c[x[i] = r[i]]++;
for (i = 1; i < m; i++) c[i] += c[i - 1];
for (i = n - 1; i >= 0; i--) sa[--c[x[i]]] = i;
for (k = 1, p = 1; k < n; k *= 2, m = p)
{
for (p = 0, i = n - k; i < n; i++) y[p++] = i;
for (i = 0; i < n; i++) if (sa[i] >= k) y[p++] = sa[i] - k;
for (i = 0; i < m; i++) c[i] = 0;
for (i = 0; i < n; i++) c[x[y[i]]]++;
for (i = 1; i < m; i++) c[i] += c[i - 1];
for (i = n - 1; i >= 0; i--) sa[--c[x[y[i]]]] = y[i];
swap(x, y);
p = 1;
x[sa[0]] = 0;
for (i = 1; i < n; i++) x[sa[i]] = cmp(y, sa[i - 1], sa[i], k) ? p - 1 : p++;
}
n--;
}
void getHeight()
{
int i, j, k = 0;
for (i = 1; i <= n; i++) rank[sa[i]] = i;
for (i = 0; i < n; i++)
{
if (k) k--;
j = sa[rank[i] - 1];
while (r[i + k] == r[j + k]) k++;
height[rank[i]] = k;
}
}
int d[maxn][20];
void RMQ_init(int A[], int n)
{
for (int i = 1; i <= n; i++) d[i][0] = A[i];
for (int j = 1; (1 << j) <= n; j++)
for (int i = 1; i + (1 << (j - 1)) <= n; i++)
d[i][j] = min(d[i][j - 1], d[i + (1 << (j - 1))][j - 1]);
}
int RMQ(int L, int R)
{
int k = 0;
while ((1 << (k + 1)) <= R - L + 1) k++;
return min(d[L][k], d[R - (1 << k) + 1][k]);
}
void LCP_init()
{
RMQ_init(height, n);
}
int lcp(int i, int j)
{
if(i == j) return 1;
if (rank[i] > rank[j]) swap(i, j);
return RMQ(rank[i] + 1, rank[j]);
}
void call_fun(char* s)
{
init(s);
build_sa();
getHeight();
LCP_init();
}
LL solve(int len)
{
LL ret = 0;
int l = 1, r = 0, tmp = 0;
for(int i = 1; i <= n; i ++)
{
while(l < i && lcp(sa[l], sa[i]) == 0)
{
if(sa[l] > 0 && sa[l] < len) tmp --;
l ++;
}
while(r < n && lcp(sa[i], sa[r + 1]) > 0)
{
r ++;
if(sa[r] > 0 && sa[r] < len) tmp ++;
}
if(sa[i] >= len && sa[i] < n - 1) ret += tmp;
}
return ret;
}
} sol;
void solve()
{
int len1 = strlen(ch1), len2 = strlen(ch2);
LL ans = 1ll * len1 * len2;
ch1[len1 ++] = '#';
for(int i = 0; i < len2; i ++)
{
ch1[len1 ++] = ch2[i];
}
ch1[len1] = 0;
sol.call_fun(ch1);
ans -= sol.solve(len1 - len2);
printf("%I64d\n", ans);
}
map<string, int> mp;
void baoli()
{
mp.clear();
int len1 = strlen(ch1), len2 = strlen(ch2);
string tmp = "";
for(int i = 0; i < len1; i ++)
{
tmp += ch1[i];
string tmp2 = "";
for(int j = len2 - 1; j >= 0; j --)
{
tmp2 += ch2[j];
reverse(tmp2.begin(), tmp2.end());
mp[tmp + tmp2] ++;
reverse(tmp2.begin(), tmp2.end());
}
}
printf("%d -- \n", mp.size());
}
/**
hsdoisdfao
sdfjisdfjiosdfji
hsdo
sdfj
*/
int main()
{
freopen("concatenation.in", "r", stdin);
freopen("concatenation.out", "w", stdout);
while(scanf("%s%s", ch1, ch2) != EOF)
{
// baoli();
solve();
}
return 0;
}
D- Distribution in Metagonia
不知道题意。
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<map>
#define xx first
#define yy second
#define LL unsigned long long
#define MP make_pair
#define INF 0x3f3f3f3f
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1|1
#define CLR(a, b) memset(a, b, sizeof(a))
using namespace std;
int main ()
{
int t;
freopen("distribution.in", "r", stdin);
freopen("distribution.out", "w", stdout);
cin >> t;
while(t --)
{
LL n;
cin >> n;
vector<LL> ans;
while(n)
{
int cnt = 0;
for(LL now = 2; ; now *= 2)
{
if(n % now) break;
cnt ++;
}
LL tmp = 1ll << cnt;
for(;;)
{
if(tmp * 3 <= n)
{
tmp *= 3;
}
else
{
break;
}
}
ans.push_back(tmp);
n -= tmp;
}
printf("%d\n", ans.size());
LL o = 0;
for(int i = 0; i < ans.size(); i ++)
{
printf("%I64u ", ans[i]);
o += ans[i];
}
puts("");
}
return 0;
}
简单题。
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<map>
#define xx first
#define yy second
#define LL long long
#define MP make_pair
#define INF 0x3f3f3f3f
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1|1
#define CLR(a, b) memset(a, b, sizeof(a))
using namespace std;
char s[1024];
char num[1024];
int main(){
freopen("easy.in","r",stdin);
freopen("easy.out","w",stdout);
while(scanf("%s",s)!=EOF){
int n=strlen(s);
for(int i=0;i<n;i++){
if(s[i]=='+'){
putchar(s[i]);
int j;
for(j=i+1;j<n&&s[j]<='9'&&s[j]>='0';j++) putchar(s[j]);
i=j-1;
}else if(s[i]=='-'){
putchar(s[i]);
int l=0,j;
memset(num,0,sizeof(num));
for(j=i+1;j<n&&s[j]<='9'&&s[j]>='0';j++) num[l++]=s[j];
i=j-1;
int st = l;
putchar(num[0]);
for(int j=1;j<l;j++){
if(num[j]=='0') printf("+%c",num[j]);
else{
putchar('+');st=j;break;
}
}
for(int j=st;j<l;j++) putchar(num[j]);
}else putchar(s[i]);
}
puts("");
memset(s,0,sizeof(s));
}
}
G- Graph
题意是要最多+k条边使得字典序最小的拓扑序最大。
首先,对于当前度为0的点个数为sz,如果k>sz-1的话,是可以把最大那个点作为当前拓扑位置的,然后把比较小的那些非配一个未连入的度。否则如果存在未分配度的点u,大于当前度为0的点的话。可以把u放到当前拓扑序的位置(注意加边)。然后当k不够的时候,肯定需要把度为0的那些点中最小的k个分配一个未连入度。然后当k=0时,把有未连入度的点尽量往后放就好了。
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<unordered_map>
#define xx first
#define yy second
#define LL unsigned long long
#define MP make_pair
#define INF 0x3f3f3f3f
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1|1
#define CLR(a, b) memset(a, b, sizeof(a))
using namespace std;
const int maxn = 200000;
vector <int> v[maxn];
int in[maxn];
priority_queue<int> q, q2;
vector<pair<int, int> > ans;
int main ()
{
freopen("graph.in", "r", stdin);
freopen("graph.out", "w", stdout);
int n, m, k;
while(scanf("%d%d%d", &n, &m, &k) != EOF)
{
CLR(in, 0);
for(int i = 0; i <= n; i ++)
{
v[i].clear();
}
ans.clear();
for(int i = 0; i < m; i ++)
{
int a, b;
scanf("%d%d", &a, &b);
in[b] ++;
v[a].push_back(b);
}
while(!q.empty()) q.pop();
for(int i = 1; i <= n; i ++)
{
if(in[i] == 0) q.push(i);
}
while(!q2.empty()) q2.pop();
int pre = 0;
while(true)
{
if(k == 0)
{
while(q.empty())
{
if(q2.empty()) break;
int now = q2.top();
q2.pop();
ans.push_back(MP(pre, now));
pre = now;
for(int i = 0; i < v[now].size(); i ++)
{
int to = v[now][i];
if(-- in[to] == 0)
{
q.push(- to);
}
}
}
if(q.empty()) break;
while(!q.empty())
{
int now = -q.top(); q.pop();
pre = now;
for(int i = 0; i < v[now].size(); i ++)
{
int to = v[now][i];
if(-- in[to] == 0)
{
q.push(- to);
}
}
}
continue;
}
while(q.empty())
{
if(q2.empty()) break;
int now = q2.top();
q2.pop();
ans.push_back(MP(pre, now));
pre = now;
for(int i = 0; i < v[now].size(); i ++)
{
int to = v[now][i];
if(-- in[to] == 0)
{
q.push(to);
}
}
}
if(q.empty()) break;
if(!q2.empty() && q.top() < q2.top())
{
if(k <= q.size())
{
vector<int> tmp;
while(!q.empty()) tmp.push_back(q.top()), q.pop();
sort(tmp.begin(), tmp.end());
for(int i = 0; i < k; i ++)
{
q2.push(tmp[i]);
}
for(int i = k; i < tmp.size(); i ++)
{
q.push(-tmp[i]);
}
k = 0;
continue;
}
int now = q2.top();
q2.pop();
ans.push_back(MP(pre, now));
pre = now;
k -= q.size();
while(!q.empty())
{
q2.push(q.top());
q.pop();
}
for(int i = 0; i < v[now].size(); i ++)
{
int to = v[now][i];
if(-- in[to] == 0)
{
q.push(to);
}
}
continue;
}
if(k <= q.size() - 1)
{
vector<int> tmp;
while(!q.empty()) tmp.push_back(q.top()), q.pop();
sort(tmp.begin(), tmp.end());
for(int i = 0; i < k; i ++)
{
q2.push(tmp[i]);
}
for(int i = k; i < tmp.size(); i ++)
{
q.push(-tmp[i]);
}
k = 0;
continue;
}
k -= q.size() - 1;
int now = q.top();
q.pop();
pre = now;
while(!q.empty())
{
int tmp = q.top();
q.pop();
q2.push(tmp);
}
for(int i = 0; i < v[now].size(); i ++)
{
int to = v[now][i];
if(-- in[to] == 0)
{
q.push(to);
}
}
}
for(int i = 0; i < ans.size(); i ++)
{
v[ans[i].xx].push_back(ans[i].yy);
}
while(!q.empty()) q.pop();
CLR(in, 0);
for(int i = 1; i <= n; i ++)
{
for(int j = 0; j < v[i].size(); j ++)
{
int a = i, b = v[i][j];
in[b] ++;
}
}
for(int i = 1; i <= n; i ++)
{
if(in[i] == 0) q.push(-i);
}
vector<int> out;
while(!q.empty())
{
int now = q.top();
now = -now;
out.push_back(now);
q.pop();
for(int i = 0; i < v[now].size(); i ++)
{
int to = v[now][i];
if(-- in[to] == 0)
{
q.push(-to);
}
}
}
for(int i = 0; i < out.size(); i ++)
{
printf("%d ", out[i]);
}puts("");
printf("%d\n", ans.size());
for(int i = 0; i < ans.size(); i ++)
{
printf("%d %d\n", ans[i].xx, ans[i].yy);
}
}
return 0;
}
/**
4 1 1
3 4
*/
H- Hash Code Hacker
水题。题目给了4个相等的,所以随便组合1000个出来就好了。
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<map>
#define xx first
#define yy second
#define LL long long
#define MP make_pair
#define INF 0x3f3f3f3f
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1|1
#define CLR(a, b) memset(a, b, sizeof(a))
using namespace std;
vector<string> vec;
string st[3] = {"edHs", "fEHs", "edIT"};
void dfs(int i, string tmp)
{
if(i == 7)
{
vec.push_back(tmp);
return ;
}
for(int j = 0; j < 3; j ++)
dfs(i + 1, tmp + st[j]);
}
void init()
{
vec.clear();
dfs(0, "");
}
int main()
{
freopen("hash.in","r",stdin);
freopen("hash.out","w",stdout);
init();
// printf("%d --\n", vec.size());
int k;
while(scanf("%d", &k) != EOF)
{
for(int i = 0; i < k; i ++)
cout << vec[i] << endl;
}
return 0;
}
J- Journey to the "The World's Start"
二分花费。然后验证答案。验证的时候用线段树加速一下就好了。
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<map>
#define xx first
#define yy second
#define LL long long
#define MP make_pair
#define INF 0x3f3f3f3f
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1|1
#define CLR(a, b) memset(a, b, sizeof(a))
using namespace std;
const int maxn = 100100;
int mn[maxn << 2];
void up(int rt)
{
mn[rt] = min(mn[rt << 1], mn[rt << 1 | 1]);
}
void build(int l, int r, int rt)
{
if(l == r)
{
mn[rt] = INF;
return ;
}
int m = (l + r) >> 1;
build(lson);
build(rson);
up(rt);
}
void update(int p, int v, int l, int r, int rt)
{
if(l == r)
{
mn[rt] = v;
return ;
}
int m = (l + r) >> 1;
if(p <= m) update(p, v, lson);
else update(p, v, rson);
up(rt);
}
int query(int L, int R, int l, int r, int rt)
{
if(L <= l && r <= R)
{
return mn[rt];
}
int m = (l + r) >> 1;
int ret = INF;
if(L <= m) ret = min(ret, query(L, R, lson));
if(R > m) ret = min(ret, query(L, R, rson));
return ret;
}
int p[maxn], d[maxn];
int n, t;
bool check(int pp)
{
int r = 0;
for(int i = 1; i < n; i ++)
{
if(p[i] <= pp) r = i;
}
if(r == 0) return false;
build(1, n, 1);
update(1, 0, 1, n, 1);
for(int i = 2; i <= n; i ++)
{
int v = query(max(1, i - r), i - 1, 1, n, 1);
update(i, v + d[i], 1, n, 1);
}
return query(n, n, 1, n, 1) <= t;
}
void solve()
{
int l = 1, r = p[n - 1];
while(l <= r)
{
int mid = (l + r) >> 1;
if(check(mid)) r = mid - 1;
else l = mid + 1;
}
printf("%d\n", l);
}
int main()
{
freopen("journey.in", "r", stdin);
freopen("journey.out", "w", stdout);
while(scanf("%d%d", &n, &t) != EOF)
{
t -= n - 1;
for(int i = 1; i < n; i ++)
scanf("%d", &p[i]);
for(int i = 2; i < n; i ++)
scanf("%d", &d[i]);
d[n] = 0;
solve();
}
return 0;
}
L- Lucky Chances
水题。
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<time.h>
#include<map>
#define xx first
#define yy second
#define LL long long
#define MP make_pair
#define INF 0x3f3f3f3f
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1|1
#define CLR(a, b) memset(a, b, sizeof(a))
using namespace std;
int s[1000][1000];
int main() {
freopen("lucky.in", "r", stdin);
freopen("lucky.out", "w", stdout);
int n, m;
while(cin >> n >> m) {
for(int i = 0; i < n; i ++) {
for(int j = 0; j < m; j ++) {
scanf("%d", &s[i][j]);
}
}
int ans = 0;
for(int i = 0; i < n; i ++) {
for(int j = 0; j < m; j ++) {
int a = i - 1;
bool ok = true;
while(a >= 0) {
if(s[a][j] >= s[i][j]) ok = false;
a --;
}
if(ok) ans ++;
a = i + 1;
ok = true;
while(a < n) {
if(s[a][j] >= s[i][j]) ok = false;
a ++;
}
if(ok) ans ++;
a = j - 1;
ok = true;
while(a >= 0) {
if(s[i][a] >= s[i][j]) ok = false;
a --;
}
if(ok) ans ++;
a = j + 1;
ok = true;
while(a < m) {
if(s[i][a] >= s[i][j]) ok = false;
a ++;
}
if(ok) ans ++;
}
}
cout << ans << endl;
}
return 0;
}