2012 Multi-University Training Contest 7
2012 Multi-University Training Contest 7
A.As long as Binbin loves Sangsang
题意:在连续的n秒中,每秒会出现m个龙珠。已知初始位置,每从一个位置i,移动到另一个位置j的时候,消耗的代价为abs(i-j), 知道了每次出现的龙珠的位置及取它的代价,每一秒必须取一颗龙珠。问 n 秒之后花费的最小代价是多少。
SOL:用dp[i][j]表示i秒之后,留在第j个龙珠所在位置的最小花费,这样就有了一个$O(n*m^2)$的做法,之后很容易想到用单调队列优化,复杂度$O(n*m)$。
- #include <cmath>
- #include <cstdio>
- #include <cstring>
- #include <iostream>
- #include <algorithm>
- using namespace std;
- const int oo = 1e9;
- int i, j, k, n, m, s, t, ans, x;
- struct node {
- int pos, cost;
- } a[][];
- int dp[][];
- bool cmp(const node &x, const node &y) {
- return x.pos < y.pos;
- }
- int main() {
- int T;
- scanf("%d", &T);
- while (T--) {
- scanf("%d %d %d", &n, &m, &x);
- for (int i = ; i <= n; i++) {
- for (int j = ; j <= m; j++) {
- scanf("%d", &a[i][j].pos);
- }
- }
- for (int i = ; i <= n; i++) {
- for (int j = ; j <= m; j++) {
- scanf("%d", &a[i][j].cost);
- }
- }
- for (int i = ; i <= n; i++) {
- sort(a[i] + , a[i] + + m, cmp);
- }
- for (int j = ; j <= m; j++) {
- dp[][j] = a[][j].cost + abs(a[][j].pos - x);
- }
- for (int i = ; i <= n; i++) {
- int k = , t = oo;
- for (int j = ; j <= m; j++) {
- while (k + <= m && a[i][j].pos >= a[i - ][k + ].pos) {
- k++;
- t = min(t, dp[i - ][k] - a[i - ][k].pos);
- }
- dp[i][j] = t + a[i][j].cost + a[i][j].pos;
- }
- k = m + , t = oo;
- for (int j = m; j >= ; j--) {
- while (k - >= && a[i][j].pos <= a[i - ][k - ].pos) {
- k--;
- t = min(t, dp[i - ][k] + a[i - ][k].pos);
- }
- dp[i][j] = min(dp[i][j], t + a[i][j].cost - a[i][j].pos);
- }
- }
- ans = oo;
- for (int j = ; j <= m; j++) {
- ans = min(ans, dp[n][j]);
- }
- printf("%d\n", ans);
- }
- return ;
- }
题意:给你n*n的方格纸,在格子里填颜色,要满足任意水平、垂直翻转,转任意个90度后看到的图形都一样;现在你有k种颜色,有m个格子已经图了颜色,求方案数。
SOL:直接搞出等价类再用快速幂做一做就好了。
- #include <cstdio>
- #include <cstring>
- #include <iostream>
- #include <algorithm>
- using namespace std;
- typedef long long ll;
- const int mod = ;
- const int LEN = 1e5 + ;
- int i, j, k, n, m, s, t, ans, tot;
- int a[LEN];
- int pow_mod(const int &x, int y) {
- if (y == ) {
- return ;
- }
- int ans = pow_mod(x, y >> );
- ans = (ll)ans * ans % mod;
- if (y & ) {
- ans = (ll)ans * x % mod;
- }
- return ans;
- }
- int trans(int x, int y) {
- if (x > n / ) {
- x = n + - x;
- }
- if (y > n / ) {
- y = n + - y;
- }
- if (x > y) {
- swap(x, y);
- }
- return x * + y;
- }
- int getnum(int n) {
- int L = (n + ) / ;
- return (L + ) * L / ;
- }
- int main() {
- while (scanf("%d %d %d", &n, &m, &k) != EOF) {
- tot = ;
- for (int i = ; i <= m; i++) {
- int x, y;
- scanf("%d %d", &x, &y);
- x++, y++;
- a[++tot] = trans(x, y);
- }
- if (tot > ) {
- sort(a + , a + + tot);
- tot = unique(a + , a + + tot) - a - ;
- }
- printf("%d\n", pow_mod(k, getnum(n) - tot));
- }
- return ;
- }
题意:给你一棵树,每个结点有两个属性值,1.能力值,2.忠诚度。然后m个询问,每次询问一个整数u,求u的子树中能力值大于u的且忠诚度最大的点的编号。
SOL:先按能力值排序,这样从大到小考虑就满足了条件1,然后从大到小依次在线段树里查询子树中忠诚度最大的点的编号,复杂度O(nlogn)。
- #include <cstdio>
- #include <cstring>
- #include <iostream>
- #include <algorithm>
- #define tl (p << 1)
- #define tr (p << 1 | 1)
- using namespace std;
- const int LEN = 1e5 + ;
- int i, j, k, n, m, s, t, tot, Time;
- struct edge {
- int vet, next;
- } E[LEN * ];
- struct node {
- int x, y, id;
- } a[LEN];
- bool cmp(const node &x, const node &y) {
- return x.x > y.x;
- };
- int head[LEN], size[LEN], tid[LEN], ans[LEN], pre[LEN], b[LEN];
- int to[];
- int tmax[LEN * ];
- void add(int u, int v) {
- E[++tot] = (edge){v, head[u]};
- head[u] = tot;
- }
- void dfs(int u) {
- size[u] = ;
- tid[u] = ++Time;
- pre[Time] = u;
- for (int e = head[u]; e != -; e = E[e].next) {
- int v = E[e].vet;
- dfs(v);
- size[u] += size[v];
- }
- }
- int ask(int l, int r, int x, int y, int p) {
- if (l == x && y == r) {
- return tmax[p];
- }
- int mid = (l + r) >> ;
- if (mid >= y) {
- return ask(l, mid, x, y, tl);
- } else if (mid + <= x) {
- return ask(mid + , r, x, y, tr);
- } else {
- return max(ask(l, mid, x, mid, tl), ask(mid + , r, mid + , y, tr));
- }
- }
- void update(int p) {
- tmax[p] = max(tmax[tl], tmax[tr]);
- }
- void modify(int l, int r, const int &x, int p, const int &c) {
- if (l == r) {
- tmax[p] = c;
- return;
- }
- int mid = (l + r) >> ;
- if (mid >= x) {
- modify(l, mid, x, tl, c);
- } else {
- modify(mid + , r, x, tr, c);
- }
- update(p);
- }
- void build(int l, int r, int p) {
- if (l == r) {
- tmax[p] = -;
- return;
- }
- int mid = (l + r) >> ;
- build(l, mid, tl);
- build(mid + , r, tr);
- update(p);
- }
- int main() {
- int T;
- scanf("%d", &T);
- while (T--) {
- tot = Time = ;
- scanf("%d %d", &n, &m);
- for (int i = ; i <= n; i++) {
- head[i] = -;
- size[i] = ;
- tid[i] = ;
- }
- a[] = (node){1e9, , };
- for (int i = ; i <= n; i++) {
- int fa, x, y;
- scanf("%d %d %d", &fa, &x, &y);
- x++,y++,fa++;
- swap(x, y);
- add(fa, i);
- a[i] = (node){x, y, i};
- to[y] = i;
- }
- dfs();
- build(, n, );
- sort(a + , a + + n, cmp);
- int j = ;
- for (int i = ; i <= n; i++) {
- int x = a[i].id, t = ask(, n, tid[x], tid[x] + size[x] - , );
- if (t == -) {
- ans[x] = ;
- } else {
- ans[x] = to[t];
- }
- while (j + <= i && a[j + ].x > a[i + ].x) {
- modify(, n, tid[a[j + ].id], , a[j + ].y);
- j++;
- }
- }
- while (m--) {
- int x;
- scanf("%d", &x);
- printf("%d\n", ans[x + ] - );
- }
- }
- return ;
- }
2012 Multi-University Training Contest 7的更多相关文章
- 2012 Multi-University Training Contest 9 / hdu4389
2012 Multi-University Training Contest 9 / hdu4389 打巨表,实为数位dp 还不太懂 先这样放着.. 对于打表,当然我们不能直接打,这里有技巧.我们可以 ...
- HDU4888 Redraw Beautiful Drawings(2014 Multi-University Training Contest 3)
Redraw Beautiful Drawings Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 65536/65536 K (Jav ...
- HDU 2018 Multi-University Training Contest 3 Problem A. Ascending Rating 【单调队列优化】
任意门:http://acm.hdu.edu.cn/showproblem.php?pid=6319 Problem A. Ascending Rating Time Limit: 10000/500 ...
- 2015 Multi-University Training Contest 8 hdu 5390 tree
tree Time Limit: 8000ms Memory Limit: 262144KB This problem will be judged on HDU. Original ID: 5390 ...
- hdu 4946 2014 Multi-University Training Contest 8
Area of Mushroom Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) ...
- 2016 Multi-University Training Contest 2 D. Differencia
Differencia Time Limit: 10000/10000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Tot ...
- 2016 Multi-University Training Contest 1 G. Rigid Frameworks
Rigid Frameworks Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) ...
- 2014 Multi-University Training Contest 9#11
2014 Multi-University Training Contest 9#11 Killing MonstersTime Limit: 2000/1000 MS (Java/Others) ...
- 2014 Multi-University Training Contest 9#6
2014 Multi-University Training Contest 9#6 Fast Matrix CalculationTime Limit: 2000/1000 MS (Java/Oth ...
随机推荐
- delphi ----Raize(第三方控件) TRzNumericEdit
一.Raize Edits 1.TRzNumericEdit IntegerOnly属性设置为false,可以输入小数. DisplayFormat := ',0.00;(,0.00)';;//小数默 ...
- 2015-03-10——简析javascript对象
对于构造函数,它是Function对象的一个实例,可以定义自己的静态成员先实例化出对象,后执行function中内部代码 静态成员: var abc = function () {}; //既是一 ...
- python常用方法详解
1,讲序列分解为单独的变量 p=(4,5) x,y=p print(x,y) 如果在分解中想丢弃某些特定的值,可以采用_来进行 data=['A','B','c','d'] _,name,age,_= ...
- Python3+Selenium3自动化测试-(三)
selenium键盘事件 #coding=utf-8 from selenium import webdriver import time from selenium.webdriver.common ...
- go项目找不到包问题
最近学习go语言,但是在主函数中引入其他包(自定义包)中方法的时候,编译代码,显示找不到包,如: $GOPATH>go build stacker.gostacker.go:18:2: cann ...
- blogCMS整理
一.在urls中写路由 二.返回登录页面(login.html中写前端代码) - username(用户名) - password(密码) - validCode(验证码) -submit(提交按钮) ...
- shiro 拦截器
参考
- Leaflet API 翻译(二)
摘自:http://www.ithao123.cn/content-824673.html L.Point 显示以像素为单位的点的x,y坐标. 所以接受点对象的leaflet方法和选项都也接受他们简单 ...
- Linux命令(6/28)——declare/typeset命令
declare 与 typeset 命令是bash的内建命令,两者是完全一样的,用来声明shell变量,设置变量的属性. declare命令(别名typeset)属shell内建命令,用于申明shel ...
- Linux 上下左右键变成^A,^B,^C,^D解决方法
用gedit打开 /etc/vim/vimrc.tiny,将里面的 set compatible 改成 set nocompatible 对于退格键backspace的问题,只需在刚才那句话下面加上一 ...