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. laravel 5.3 多用户认证

    不知道对不对,乱来一下!!!! 1)laravel自带了一个用户认证系统,要使用的话,直接运行一下命令就可以用了 php artisan make:auth 会生成相应的控制器.路由和模版文件 2)数 ...

  2. 查看进程动态:top

    top命令用于查看进程动态,即进程使用系统资源的情况,常见用法如下: [root@localhost ~]$ top # 动态查看进程使用资源的情况,每三秒刷新一次 [root@localhost ~ ...

  3. Python 使用正则表达式匹配URL网址

    使用正则表达式匹配以 .com 或 .cn 为域名后缀的URL地址 In [1]: import re In [2]: str = "http://www.baidu.com/" ...

  4. c++11——tuple元组

    tuple是一个固定大小的不同类型值的集合,是泛化的 std::pair.可以当做一通用的结构体使用,不需要创建结构体而又获取结构体的特征,在某些情况下可以取代结构体,使程序简洁.直观. 创建tupl ...

  5. 非旋转Treap

    Treap是一种平衡二叉树,同时也是一个堆.它既具有二叉查找树的性质,也具有堆的性质.在对数据的查找.插入.删除.求第k大等操作上具有期望O(log2n)的复杂度.     Treap可以通过节点的旋 ...

  6. redis 之初体验(window)

    1 下载window版本的redis :https://github.com/MSOpenTech/redis/releases 2 解压压缩包.我的放在了E盘: E:/redis 3 程序,输入cm ...

  7. xcode 4.6 破解及真机调试

    从安卓到IOS,从  eclipse 到xcode跨度还是比较大的.在研究的过程中发现,许多时候不仅仅是C,C++,JAVA和OBJECT-C的区别,相对于编程语言来说,操作习惯和开发工具带来的困惑要 ...

  8. redis基础----->redis的基本使用(一)

    这里我们就在虚拟机中安装redis,并且使用java和python实现简单的操作.深情是我承担不起的重担,情话只是偶尔兑现的谎言. redis的使用 下载地址:https://redis.io/.安装 ...

  9. 数据一致性和io类型

    版权声明:本文由高剑林原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/106 来源:腾云阁 https://www.qclo ...

  10. deferred对象(摘自别人的文章)

    对jQuery中的deferred对象的整体认识: Deferred是个工厂类,返回的是内部构建的deferred对象 tuples 创建三个$.Callbacks对象,分别表示成功,失败,处理中三种 ...