A - Problem A. Ascending Rating

题意:给出n个数,给出区间长度m。对于每个区间,初始值的max为0,cnt为0.遇到一个a[i] > ans, 更新ans并且cnt++。计算

$A = \sum_{i = 1}^{i = n - m +1} (max \oplus i)$

$B = \sum_{i = 1}^{i = n - m +1} (cnt \oplus i)$

思路:单调队列,倒着扫一遍,对于每个区间的cnt就是队列的长度,扫一遍即可。

 #include<bits/stdc++.h>

 using namespace std;

 const int maxn = 1e7 + ;
typedef long long ll; int t;
int n,m,k;
ll p, q, r, mod;
ll arr[maxn];
ll brr[maxn]; int main()
{
scanf("%d", &t);
while(t--)
{
scanf("%d %d %d %lld %lld %lld %lld", &n, &m, &k, &p, &q, &r, &mod);
for(int i = ; i <= n; ++i)
{
if(i <= k) scanf("%lld", arr + i);
else arr[i] = (p * arr[i - ] + q * i + r) % mod;
}
ll A = , B = ;
int head = , tail = -;
for(int i = n; i > (n - m + ); --i)
{
while(head <= tail && arr[i] >= arr[brr[tail]]) tail--;
brr[++tail] = i;
}
for(int i = n - m + ; i >= ; --i)
{
while(head <= tail && arr[i] >= arr[brr[tail]]) tail--;
brr[++tail] = i;
while(brr[head] - i >= m) head++;
A += arr[brr[head]] ^ i;
B += (tail - head + ) ^ i;
}
printf("%lld %lld\n", A, B);
}
return ;
}

B - Problem B. Cut The String

留坑。

C - Problem C. Dynamic Graph Matching

题意:给出n个点,两种操作,一种是加边,一种是减边,每次加一条或者减一条,每次操作后输出1, 2, ..., n/2 表示对应的数量的边,有几种取法,并且任意两个边不能相邻

思路:每加一条边,都可以转移状态 比如说 110100 到  111110 就是 dp[111110] += dp[110100]

 #include<bits/stdc++.h>

 using namespace std;

 typedef long long ll;
const int maxn = << ;
const int MOD = 1e9 + ; int t, n, m;
ll dp[maxn];
ll ans[]; inline int cal(int x)
{
int cnt = ;
while(x)
{
if(x & ) cnt++;
x >>= ;
}
return cnt;
} int main()
{
scanf("%d", &t);
while(t--)
{
memset(ans, , sizeof ans);
memset(dp, , sizeof dp);
dp[] = ;
scanf("%d %d", &n, &m);
while(m--)
{
char op[];
int u, v;
scanf("%s %d %d", op, &u, &v);
--u,--v;
for(int s = ; s < ( << n); ++s)
{
if((s & ( << u)) || (s & ( << v))) continue;
int S = s | ( << u);
S |= ( << v);
if(op[] == '+')
{
dp[S] = (dp[S] + dp[s]) % MOD;
ans[cal(S)] = (ans[cal(S)] + dp[s]) % MOD;
}
else if(op[] == '-')
{
dp[S] = (dp[S] - dp[s] + MOD) % MOD;
ans[cal(S)] = (ans[cal(S)] - dp[s] + MOD) % MOD;
}
}
for(int i = ; i <= n; i += )
{
printf("%lld%c", ans[i], " \n"[i == n]);
}
}
}
return ;
}

D - Problem D. Euler Function

打表找规律

 #include <bits/stdc++.h>

 using namespace std;

 #define N 100010

 inline int gcd(int a, int b)
{
return b == ? a : gcd(b, a % b);
} inline void Init()
{
for (int i = ; i <= ; ++i)
{
int res = ;
for (int j = ; j < i; ++j)
res += (gcd(i, j) == );
printf("%d %d\n", i, res);
}
} int t, n; int main()
{
scanf("%d", &t);
while (t--)
{
scanf("%d", &n);
if (n == ) puts("");
else printf("%d\n", n + );
}
return ;
}

E - Problem E. Find The Submatrix

留坑,

F - Problem F. Grab The Tree

题意:一棵树,每个点有点权,小Q可以选择若干个点,并且任意两个点之间没有边,小T就是剩下的所有点,然后两个人的值就是拥有的点异或起来,求小Q赢还是输还是平局

思路:显然,只有赢或者平局的情况,只要考虑是否有平局情况就可以,当所有点异或起来为0便是平局

 #include <bits/stdc++.h>
using namespace std; #define N 100010 int t, n;
int arr[N]; int main()
{
scanf("%d", &t);
while (t--)
{
scanf("%d", &n);
int res = ;
for (int i = ; i <= n; ++i)
{
scanf("%d", arr + i);
res ^= arr[i];
}
for (int i = , u, v; i < n; ++i) scanf("%d%d", &u, &v);
if (res == )
{
puts("D");
continue;
}
puts("Q");
}
return ;
}

G - Problem G. Interstellar Travel

题意:给出n个点,要从$i -> j$ 当且仅当 $x_i < x_j$ 花费为 $x_i \cdot y_j - x_j \cdot y_i$ 求从$1 -> n$ 求权值最小如果多解输出字典序最小的解

思路:可以发现权值就是叉积,求个凸包,然后考虑在一条线上的情况

 #include <bits/stdc++.h>
using namespace std; #define N 200010 const double eps = 1e-; inline int sgn(double x)
{
if (fabs(x) < eps) return ;
if (x < ) return -;
else return ;
} struct Point
{
double x, y; int id;
inline Point () {}
inline Point(double x, double y) : x(x), y(y) {}
inline void scan(int _id)
{
id = _id;
scanf("%lf%lf", &x, &y);
}
inline bool operator == (const Point &r) const { return sgn(x - r.x) == && sgn(y - r.y) == ; }
inline bool operator < (const Point &r) const { return x < r.x || x == r.x && y < r.y || x == r.x && y == r.y && id < r.id; }
inline Point operator + (const Point &r) const { return Point(x + r.x, y + r.y); }
inline Point operator - (const Point &r) const { return Point(x - r.x, y - r.y); }
inline double operator ^ (const Point &r) const { return x * r.y - y * r.x; }
inline double distance(const Point &r) const { return hypot(x - r.x, y - r.y); }
}; struct Polygon
{
int n;
Point p[N];
struct cmp
{
Point p;
inline cmp(const Point &p0) { p = p0; }
inline bool operator () (const Point &aa, const Point &bb)
{
Point a = aa, b = bb;
int d = sgn((a - p) ^ (b - p));
if (d == )
{
return sgn(a.distance(p) - b.distance(p)) < ;
}
return d < ;
}
};
inline void norm()
{
Point mi = p[];
for (int i = ; i < n; ++i) mi = min(mi, p[i]);
sort(p, p + n, cmp(mi));
}
inline void Graham(Polygon &convex)
{
sort(p + , p + n - );
int cnt = ;
for (int i = ; i < n; ++i)
{
if (!(p[i] == p[i - ]))
p[cnt++] = p[i];
}
n = cnt;
norm();
int &top = convex.n;
top = ;
if (n == )
{
top = ;
convex.p[] = p[];
convex.p[] = p[];
return;
}
if(n == )
{
top = ;
convex.p[] = p[];
convex.p[] = p[];
convex.p[] = p[];
return ;
}
convex.p[] = p[];
convex.p[] = p[];
top = ;
for (int i = ; i < n; ++i)
{
while (top > && sgn((convex.p[top - ] - convex.p[top - ]) ^ (p[i] - convex.p[top - ])) >= )
{
if(sgn((convex.p[top - ] - convex.p[top - ]) ^ (p[i] - convex.p[top - ])) == )
{
if(p[i].id < convex.p[top - ].id) --top;
else break;
}
else
{
--top;
}
}
convex.p[top++] = p[i];
}
if (convex.n == && (convex.p[] == convex.p[])) --convex.n;
}
}arr, ans; int t, n; int main()
{
scanf("%d", &t);
while (t--)
{
scanf("%d", &n); arr.n = n;
// cout << n << endl;
for (int i = ; i < n; ++i) arr.p[i].scan(i + );
arr.Graham(ans);
for (int i = ; i < ans.n; ++i) printf("%d%c", ans.p[i].id, " \n"[i == ans.n - ]);
}
return ;
}

H - Problem H. Monster Hunter

留坑。

I - Problem I. Random Sequence

留坑。

J - Problem J. Rectangle Radar Scanner

留坑。

K - Problem K. Transport Construction

留坑。

L - Problem L. Visual Cube

按题意模拟即可,分块解决

 #include <bits/stdc++.h>
using namespace std; int t, a, b, c, n, m;
char ans[][]; int main()
{
scanf("%d", &t);
while (t--)
{
memset(ans, , sizeof ans);
scanf("%d%d%d", &a, &b, &c);
n = (b + c) * + ;
m = (a + b) * + ;
for (int i = n, cnt = ; cnt <= c; ++cnt, i -= )
{
for (int j = ; j <= * a; j += )
ans[i][j] = '+', ans[i][j + ] = '-';
}
for (int i = n - , cnt = ; cnt <= c; ++cnt, i -= )
{
for (int j = ; j <= * a; j += )
ans[i][j] = '|';
}
for (int i = * b + , tmp = , cnt = ; cnt <= b + ; ++cnt, i -=, tmp += )
{
for (int j = + tmp, cntt = ; cntt <= a; ++cntt, j += )
ans[i][j] = '+', ans[i][j + ] = '-';
}
for (int i = * b, tmp = , cnt = ; cnt <= b; ++cnt, tmp += , i -= )
{
for (int j = + tmp, cntt = ; cntt <= a; ++cntt, j += )
ans[i][j] = '/';
}
for (int j = m, cntt = , tmp = ; cntt <= b + ; ++cntt, j -= , tmp += )
{
for (int i = + tmp, cnt = ; cnt <= c + ; ++cnt, i += )
{
ans[i][j] = '+';
if (cnt <= c) ans[i + ][j] = '|';
}
}
for (int j = m - , tmp = , cntt = ; cntt <= b; ++cntt, tmp += , j -= )
{
for (int i = + tmp, cnt = ; cnt <= c + ; ++cnt, i += )
ans[i][j] = '/';
}
for (int i = ; i <= n; ++i)
{
for (int j = ; j <= m; ++j)
if (!ans[i][j]) ans[i][j] = '.';
ans[i][m + ] = ;
printf("%s\n", ans[i] + );
}
}
return ;
}

M - Problem M. Walking Plan

题意:给出一张图,询问从$u -> v 至少经过k条路的最少花费$

思路:因为$k <= 10000$ 那么我们可以拆成 $k = x * 100 + y$ 然后考虑分块

$G[k][i][j] 表示 i -> j 至少经过k条路$

$dp[k][i][j] 表示 i -> j 至少经过 k * 100 条路$

然后查询的时候枚举中间点

 #include <bits/stdc++.h>
using namespace std; #define N 210
#define INFLL 0x3f3f3f3f3f3f3f3f
#define ll long long int t, n, m, q;
ll G[N][][], dp[N][][]; inline void Init()
{
memset(G, 0x3f, sizeof G);
memset(dp, 0x3f, sizeof dp);
} inline void Floyd()
{
for (int l = ; l <= ; ++l)
for (int k = ; k <= n; ++k)
for (int i = ; i <= n; ++i)
for (int j = ; j <= n; ++j)
G[l][i][j] = min(G[l][i][j], G[l - ][i][k] + G[][k][j]);
for (int i = ; i <= n; ++i)
for (int j = ; j <= n; ++j)
for (int l = ; l >= ; --l)
G[l][i][j] = min(G[l][i][j], G[l + ][i][j]); // at least K roads;
for (int i = ; i <= n; ++i)
for (int j = ; j <= n; ++j)
dp[][i][j] = G[][i][j];
for (int l = ; l <= ; ++l)
for (int k = ; k <= n; ++k)
for (int i = ; i <= n; ++i)
for (int j = ; j <= n; ++j)
dp[l][i][j] = min(dp[l][i][j], dp[l - ][i][k] + dp[][k][j]);
} inline void Run()
{
scanf("%d", &t);
while (Init(), t--)
{
scanf("%d%d", &n, &m);
for (int i = , u, v, w; i <= m; ++i)
{
scanf("%d%d%d", &u, &v, &w);
G[][u][v] = min(G[][u][v], (ll)w);
}
Floyd(); scanf("%d", &q);
for (int i = , u, v, k; i <= q; ++i)
{
scanf("%d%d%d", &u, &v, &k);
int unit = floor (k * 1.0 / ), remind = k - unit * ;
ll ans = INFLL;
if (k <= ) ans = G[k][u][v];
else
{
for (int j = ; j <= n; ++j)
ans = min(ans, dp[unit][u][j] + G[remind][j][v]);
}
if (k > && remind == ) ans = min(ans, dp[unit][u][v]);
printf("%lld\n", ans >= INFLL ? - : ans);
}
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ;
}

2018 Multi-University Training Contest 3 Solution的更多相关文章

  1. 2018 Multi-University Training Contest 1 Solution

    A - Maximum Multiple 题意:给出一个n 找x, y, z 使得$n = x + y +z$ 并且 $n \equiv 0 \pmod x, n \equiv 0 \pmod y, ...

  2. 2018 Multi-University Training Contest 2 Solution

    A - Absolute 留坑. B - Counting Permutations 留坑. C - Cover 留坑. D - Game puts("Yes") #include ...

  3. 2018 Multi-University Training Contest 4 Solution

    A - Problem A. Integers Exhibition 留坑. B - Problem B. Harvest of Apples 题意:计算$\sum_{i = 0}^{i = m}C( ...

  4. 2018 Multi-University Training Contest 5 Solution

    A - Always Online Unsolved. B - Beautiful Now Solved. 题意: 给出一个n, k  每次可以将n这个数字上的某两位交换,最多交换k次,求交换后的最大 ...

  5. 2018 Multi-University Training Contest 6 Solution

    A - oval-and-rectangle 题意:给出一个椭圆的a 和 b,在$[0, b]中随机选择c$ 使得四个顶点在椭圆上构成一个矩形,求矩形周长期望 思路:求出每种矩形的周长,除以b(积分) ...

  6. 2018 Multi-University Training Contest 7 Solution

    A - Age of Moyu 题意:给出一张图,从1走到n,如果相邻两次走的边的权值不同,花费+1, 否则花费相同,求最小花费 思路:用set记录有当前点的最小花费有多少种方案到达,然后最短路 #i ...

  7. 2018 Multi-University Training Contest 8 Solution

    A - Character Encoding 题意:用m个$0-n-1$的数去构成k,求方案数 思路:当没有0-n-1这个条件是答案为C(k+m-1, m-1),减去有大于的关于n的情况,当有i个n时 ...

  8. 2018 Multi-University Training Contest 9 Solution

    A - Rikka with Nash Equilibrium 题意:构造一个$n * m$的矩阵,使得$[1, n * m]$ 中每个数只出现一次,并且纳什均衡只出现一次. 思路:从大到小的放置,每 ...

  9. 2018 Multi-University Training Contest 10 Solution

    A - Problem A.Alkane 留坑. B - Problem B. Beads 留坑. C - Problem C. Calculate 留坑. D - Problem D. Permut ...

随机推荐

  1. mac平台安装类似yum的工具

    首先从Apple Store下载Xcode,然后安装Xcode,接着安装Homebrew包管理,类似于Ubuntu下的apt-get: 终端下输入ruby -e "$(curl -fsSL ...

  2. 一个php日志类

    <?php //author:lixiuran class Log { public static function writeLog($string) { $string = date('H: ...

  3. 使用synchronized(非this对象)同步代码块解决脏读问题

    首先通过示例来学习验证多个线程调用同一个方法时随机的. package syn_out_asyn; import java.util.ArrayList; import java.util.List; ...

  4. JS-匀速运动-运动停止

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  5. Web和Native使用外部字体ttf方法

    论坛教程:http://bbs.egret.com/forum.php?mod=viewthread&tid=24879&extra=&highlight=%E5%AD%97% ...

  6. 【BZOJ2599】[IOI2011]Race 树的点分治

    [BZOJ2599][IOI2011]Race Description 给一棵树,每条边有权.求一条简单路径,权值和等于K,且边的数量最小.N <= 200000, K <= 100000 ...

  7. oracle的with as用法

    转自:https://www.cnblogs.com/linjiqin/archive/2013/06/24/3152667.html with as语法–针对一个别名with tmp as (sel ...

  8. mybatis按姓名或手机号搜索

    1.AND ((USER_NAME LIKE '%'||#{searchKey}||'%') OR (MOBILE_PHONE LIKE '%'||#{searchKey}||'%'))2. < ...

  9. ajax解决跨域方法(适用于自己写接口解决跨域)

    原因是这样的:最近用PHP开发了一个网站,这个网站需要提供接口,接口开发完成之后,在本地进行请求,跨域测试. jsonp处理跨域和用PHP函数来处理跨域就不说了. 现在说的使用用 header 这个来 ...

  10. Oracle自动备份脚本的实现

    问题描述: Oracle自动备份脚本的实现. 错误提示1: Message file RMAN.msb not found Verify that Oracle_HOME is set properl ...