2017 ACM/ICPC 广西邀请赛 题解
题目链接 Problems
HDOJ上的题目顺序可能和现场比赛的题目顺序不一样,
我这里的是按照HDOJ的题目顺序来写的。
Problem 1001
签到
#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i) typedef long long LL; LL n, f[31];
int ans; int main(){ f[1] = 1LL;
for (LL i = 2; i <= 15; ++i){
f[i] = 1LL;
rep(j, 1, i) f[i] *= i;
} while (~scanf("%lld", &n)){
ans = 0;
rep(i, 1, 15) if (f[i] <= n) ans = max(ans, i);
printf("%d\n", ans);
} return 0;
}
Problem 1002
这道题的话,其实一个点上是可以有多种颜色的
因为最多只有51种颜色,所以我们维护51棵线段树即可。
我们对y坐标建立线段树,对于每个y,我们只需要知道最小的x在哪里即可。
因为他的询问的x坐标下界总是1,那么我们只要看看y1到y2的最小值是否小于等于给定的x即可。
询问的时候做51次子询问就可以了。
#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i)
#define dec(i, a, b) for (int i(a); i >= (b); --i) typedef long long LL; const int N = 2e6 + 10; int X, c, d, x, y, op, ans, ret, cnt;
int root[53];
int l[N], r[N], v[N]; void update(int &i, int L, int R, int x, int val){
if (i == 0){
i = ++cnt;
v[i] = val;
} v[i] = min(v[i], val);
if (L == R) return; int mid = (L + R) >> 1;
if (x <= mid) update(l[i], L, mid, x, val);
else update(r[i], mid + 1, R, x, val);
} void query(int i, int L, int R){
if (ret || i == 0) return;
if (c <= L && R <= d){
if (v[i] <= X) ret = 1;
return;
} int mid = (L + R) >> 1;
if (c <= mid) query(l[i], L, mid);
if (d > mid) query(r[i], mid + 1, R);
} int main(){ while (true){
scanf("%d", &op);
if (op == 3) break;
if (op == 0){
rep(i, 1, cnt) l[i] = r[i] = 0;
memset(root, 0, sizeof root);
cnt = 0;
} if (op == 1){
scanf("%d%d%d", &x, &y, &c);
update(root[c], 1, 1000000, y, x);
} if (op == 2){
scanf("%d%d%d", &X, &c, &d);
ans = 0;
rep(i, 0, 50){
ret = 0;
query(root[i], 1, 1000000);
ans += ret;
}
printf("%d\n", ans);
}
} return 0;
}
Problem 1003
我们对于每一条边,找到所有包含这条边的三元环,个数计为x
然后这对答案的贡献就是$C_{x}^{2}$
判断两点之间是否有边的时候要手写哈希才能过
#include <bits/stdc++.h> const int N = 2e5 + 10; #define rep(i, a, b) for (int i(a); i <= (b); ++i)
#define dec(i, a, b) for (int i(a); i >= (b); --i) namespace Hashmap{
const int P = 1000007, seed = 2333;
int u[N << 2], v[N << 2], nt[N << 2];
int head[P], inum;
inline void init(){
inum = 0;
memset(u, 0, sizeof u);
memset(v, 0, sizeof v);
memset(nt, 0, sizeof nt);
memset(head, 0, sizeof head);
} inline void add(int _u, int _v){
int t = (_u * seed + _v) % P;
u[++inum] = _u, v[inum] = _v, nt[inum] = head[t], head[t] = inum;
} inline bool query(int _u, int _v){
int t = (_u * seed + _v) % P;
for (int p = head[t]; p; p = nt[p])
if (u[p] == _u && v[p] == _v) return 1;
return 0;
}
} using namespace std;
using namespace Hashmap; typedef long long LL; vector<int> a[N]; struct ss{ int x, y; } e[N]; int n, m; int main(){ while (~scanf("%d%d",&n, &m)){
init();
rep(i, 1, n) a[i].clear();
rep(i, 1, m){
int x, y;
scanf("%d%d", &x, &y);
e[i].x = x;
e[i].y = y;
a[x].push_back(y);
a[y].push_back(x);
add(x, y);
add(y, x);
} LL ans = 0;
rep(i, 1, m){
int x = e[i].x, y = e[i].y;
if (a[e[i].y].size() < a[e[i].x].size()) swap(x, y);
LL tot = 0;
for (auto u: a[x]) if (query(u, y)) tot++;
ans += tot * (tot - 1) / 2;
} printf("%lld\n", ans);
}
return 0;
}
Problem 1004
这题规律找了半天……
$f[n] = f[n - 1] + 5f[n - 2] + f[n - 3] - f[n - 4]$
然后矩阵加速下就可以了
#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i)
#define dec(i, a, b) for (int i(a); i >= (b); --i)
#define MP make_pair
#define fi first
#define se second typedef long long LL; const LL mod = 1e9 + 7; struct Matrix{
LL arr[6][6];
} f, unit, a; LL m, k;
int n; Matrix Add(Matrix a, Matrix b){
Matrix c;
rep(i, 1, n) rep(j, 1, n){
c.arr[i][j] = (a.arr[i][j] + b.arr[i][j]) % mod;
}
return c;
} Matrix Mul(Matrix a, Matrix b){
Matrix c;
rep(i, 1, n) rep(j, 1, n){
c.arr[i][j] = 0;
rep(k, 1, n) (c.arr[i][j] += (a.arr[i][k] * b.arr[k][j] % mod)) %= mod;
}
return c;
} Matrix Pow(Matrix a, LL k){
Matrix ret(unit); for (; k; k >>= 1, a = Mul(a, a)) if (k & 1) ret = Mul(ret, a); return ret;
} int main(){ n = 4; memset(f.arr, 0, sizeof f.arr);
memset(a.arr, 0, sizeof a.arr);
memset(unit.arr, 0, sizeof unit.arr); rep(i, 1, n) unit.arr[i][i] = 1;
f.arr[1][1] = 1;
f.arr[1][2] = 5;
f.arr[1][3] = 1;
f.arr[1][4] = 1000000006;
f.arr[2][1] = 1;
f.arr[3][2] = 1;
f.arr[4][3] = 1; a.arr[1][1] = 36;
a.arr[2][1] = 11;
a.arr[3][1] = 5;
a.arr[4][1] = 1; while (~scanf("%lld", &m)){
if (m == 1LL){ puts("1"); continue;}
if (m == 2LL){ puts("5"); continue;}
if (m == 3LL){ puts("11"); continue;}
if (m == 4LL){ puts("36"); continue;}
if (m == 5LL){ puts("95"); continue;} k = m - 4; Matrix b = Pow(f, k);
Matrix c = Mul(b, a);
printf("%lld\n", c.arr[1][1]);
} return 0;
}
Problem 1010
这道题的话先转DFS序,然后求出以每个点为根的子树的对应区间,
于是就转化成了求区间里选一个数和x异或后的最大值。
可持久化trie即可。
#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i)
#define dec(i, a, b) for (int i(a); i >= (b); --i) typedef long long LL; const int N = 1e5 + 10;
const int M = 1e7 + 10; int n, m, tot = 0;
int rt[N], id[M], t[M][2];
int l, r, x;
int a[N], c[N], L[N], R[N], g[N];
int ti;
int u; vector <int> v[N]; inline void insert(int pre, int x, int k){ int now = rt[k] = ++tot; id[tot] = k; dec(i, 30, 0){
int j = (x >> i) & 1;
t[now][j ^ 1] = t[pre][j ^ 1];
t[now][j] = ++tot;
id[tot] = k;
now = t[now][j];
pre = t[pre][j];
}
} inline int query(int l, int r, int x){ int ans = 0, tmp = rt[r]; dec(i, 30, 0){
if (id[tmp] < l) break;
int j = ((x >> i) & 1) ^ 1;
if (id[t[tmp][j]] >= l) ans |= (1 << i);
else j ^= 1;
tmp = t[tmp][j];
} return ans;
} void dfs(int x){
L[x] = ++ti;
g[ti] = a[x];
for (auto u : v[x]){
dfs(u);
}
R[x] = ti;
} int main(){ while (~scanf("%d%d", &n, &m)){
memset(id, 0, sizeof id);
memset(rt, 0, sizeof rt);
memset(t, 0, sizeof t);
memset(L, 0, sizeof L);
memset(R, 0, sizeof R); tot = 0;
ti = 0; rep(i, 0, n + 1) v[i].clear();
rep(i, 1, n) scanf("%d", a + i);
rep(i, 2, n){
scanf("%d", &x);
v[x].push_back(i);
} dfs(1); id[0] = -1;
insert(0, 0, 0); rep(i, 1, n) insert(rt[i - 1], g[i], i); rep(i, 1, m){
scanf("%d%d", &u, &x);
printf("%d\n", query(L[u], R[u], x));
} }
return 0;
}
2017 ACM/ICPC 广西邀请赛 题解的更多相关文章
- 2017 ICPC 广西邀请赛1004 Covering
Covering Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Su ...
- 2017 ACM/ICPC Asia Regional Shenyang Online spfa+最长路
transaction transaction transaction Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 132768/1 ...
- 2017 ACM ICPC Asia Regional - Daejeon
2017 ACM ICPC Asia Regional - Daejeon Problem A Broadcast Stations 题目描述:给出一棵树,每一个点有一个辐射距离\(p_i\)(待确定 ...
- 2017 ACM - ICPC Asia Ho Chi Minh City Regional Contest
2017 ACM - ICPC Asia Ho Chi Minh City Regional Contest A - Arranging Wine 题目描述:有\(R\)个红箱和\(W\)个白箱,将这 ...
- 2017 ACM/ICPC Shenyang Online SPFA+无向图最长路
transaction transaction transaction Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 132768/1 ...
- 2017 ACM/ICPC Asia Regional Qingdao Online
Apple Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total Submi ...
- 2014 ACM/ICPC 北京邀请赛 部分 题解
题目链接:http://acm.bnu.edu.cn/bnuoj/problem.php?search=2014+ACM-ICPC+Beijing+Invitational+Programming+C ...
- 2017 ICPC 广西邀请赛1005 CS Course
CS Course Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total S ...
- 2017 ACM/ICPC Asia Regional Shenyang Online(部分题解)
HDU 6197 array array array 题意 输入n和k,表示输入n个整数和可以擦除的次数k,如果至多擦除k次能是的数组中的序列是不上升或者是不下降序列,就是魔力数组,否则不是. 解题思 ...
随机推荐
- gson对象的相互转换
参见 http://www.javacreed.com/gson-deserialiser-example/
- ELK日志分析 学习笔记
(贴一篇之前工作期间整理的elk学习笔记) ELK官网 https://www.elastic.co ELK日志分析系统 学习笔记 概念:ELK = elasticsearch + logstas ...
- qemu-img管理虚拟机
qemu-img管理虚拟机 1. 查看正在运行的虚拟机 [root@idca-vm02 ~]# virsh list Id 名称 状态 ----- ...
- 冒泡法排序参考(Java)
package com.swift; public class Maopao { //冒泡法 public static void main(String[] args) { int[] arr= { ...
- (17)zabbix自定义用户key与参数User parameters
为什么要自定义KEY 有时候我们想让被监控端执行一个zabbix没有预定义的检测,zabbix的用户自定义参数功能提供了这个方法. 我们可以在客户端配置文件zabbix_angentd.conf里面配 ...
- (12)zabbix agent 类型所有key
zabbix服务器端通过与zabbix agent通信来获取客户端服务器的数据,agent分为两个版本,其中一个是主动一个是被动,在配置主机我们可以看到一个是agent,另一个是agent(activ ...
- Verilog学习笔记基本语法篇(三)·········赋值语句(待补充)
在Verilog HDL语言中,信号有两种赋值方式. A)非阻塞赋值(Non-Blocking)方式(如:b<=a;) (1)在语句块中,上面语句所赋值的变量不能立即为下面的语句所用: (2)块 ...
- LeetCode 673. Number of Longest Increasing Subsequence
Given an unsorted array of integers, find the number of longest increasing subsequence. Example 1: I ...
- 16,re模块的常用方法
ret =re.findall('\d+', 'eva123egon4yuan567') print(ret)#返回满足条件的结果 ,放在一个列表里. ret2 = re.search('\d+',' ...
- HDU-1532 Drainage Ditches,人生第一道网络流!
Drainage Ditches 自己拉的专题里面没有这题,网上找博客学习网络流的时候看到闯亮学长的博客然后看到这个网络流入门题!随手一敲WA了几发看讨论区才发现坑点! 本题采用的是Edmonds-K ...