A - Buy and Resell

题意:给出n个交易点,每次能够选择买或者卖,求获得最大利润

思路:维护两个优先队列,一个是卖,一个是替换,当价格差相同时,优先替换,因为次数要最少

 #include <bits/stdc++.h>
using namespace std; #define ll long long
#define N 100010 int t, n;
ll arr[N];
priority_queue <ll, vector <ll>, greater <ll> > q[]; inline void Run()
{
scanf("%d", &t);
while (t--)
{
scanf("%d", &n);
for (int i = ; i <= n; ++i) scanf("%lld", arr + i);
for (int i = ; i < ; ++i) while (!q[i].empty()) q[i].pop();
ll ans = ;
for (int i = ; i <= n; ++i)
{
if (q[].empty() && q[].empty()) q[].emplace(arr[i]);
else if (q[].empty())
{
ll top = q[].top();
if (arr[i] > top)
{
q[].pop();
ans += arr[i] - top;
q[].emplace(arr[i]);
}
else
q[].emplace(arr[i]);
}
else if (q[].empty())
{
ll top = q[].top();
if (arr[i] > top)
{
q[].pop();
ans += arr[i] - top;
q[].emplace(top);
q[].emplace(arr[i]);
}
else
{
q[].emplace(arr[i]);
}
}
else
{
ll top1 = q[].top(), top2 = q[].top();
if (top1 < top2)
{
if (arr[i] > top1)
{
q[].pop();
ans += arr[i] - top1;
q[].emplace(arr[i]);
}
else
{
q[].emplace(arr[i]);
}
}
else
{
if (arr[i] > top2)
{
q[].pop();
ans += arr[i] - top2;
q[].emplace(top2);
q[].emplace(arr[i]);
}
else
{
q[].emplace(arr[i]);
}
}
}
}
printf("%lld %d\n", ans, q[].size() * );
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run(); return ;
}

B - Congruence equation

留坑。

C - Dream

题意:给出一个p,重定义加法和乘法,使得$(m + n)^p = m^p + n^p $

思路:有费马小定理  $a^p \equiv a \pmod p$

那只需要重定义

          $(m + n) = (m + n) \pmod p$

          $(m \cdot n) = (m \cdot n) \pmod p$

原根可以保证两个集合相等

 #include <bits/stdc++.h>
using namespace std; #define ll long long
#define N 2010 int t, p;
int a[N][N], b[N][N]; inline void Run()
{
scanf("%d", &t);
while (t--)
{
scanf("%d", &p);
for (int i = ; i < p; ++i)
{
for (int j = ; j < p; ++j)
{
a[i][j] = (i + j) % p;
b[i][j] = (i * j) % p;
}
}
for (int i = ; i < p; ++i)
{
for (int j = ; j < p; ++j)
{
printf("%d%c", a[i][j], " \n"[j == p - ]);
}
}
for (int i = ; i < p; ++i)
{
for (int j = ; j < p; ++j)
{
printf("%d%c", b[i][j], " \n"[j == p - ]);
}
}
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run(); return ;
}

D - Find Integer

题意:给出一个n和一个a  找出 $a^n + b^n = c^n$

思路:根据费马大定理 n > 2 无解  显然 n = 0 无解

n = 1  直接凑

n = 2  如果是奇数 有 $a^2 + (\frac{a \cdot a}{2})^2 = (\frac{(a \cdot a) + 1}{2}) ^2$

如果是偶数 一直除下去 知道是奇数 然后把多余的偶数加到b 和 c 上去

或者

 #include <bits/stdc++.h>
using namespace std; #define ll long long
#define INF 0x3f3f3f3f
#define N 40010 int t;
ll n, a, cnt; ll arr[N][]; inline void Run()
{
for (int i = ; i <= ; ++i)
{
cnt = ;
ll a = i;
while ((a & ) == && a > )
{
cnt <<= ;
a >>= ;
}
if (a == )
{
arr[i][] = cnt * , arr[i][] = cnt * ;
}
else
{
ll b = a * a / ;
ll c = b + ;
arr[i][] = b * cnt;
arr[i][] = c * cnt;
}
}
scanf("%d", &t);
while (t--)
{
scanf("%lld%lld", &n, &a);
if (n == || n >= )
{
puts("-1 -1");
continue;
}
if (n == )
{
printf("1 %lld\n", a + );
continue;
}
printf("%lld %lld\n", arr[a][], arr[a][]);
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run(); return ;
}

E - GuGu Convolution

留坑。

F - Neko and Inu

留坑。

G - Neko's loop

题意:给出一个长度为n的数列,每个位置都有自己的权值,你有m点能量,每次可以从i走到(i+k)%n点,可以再任意时刻停止,为达到s点能量,需要起始能量为多少。

思路:可以通过o(n)的时间处理出循环节。对于每个循环节,我们可以走完循环节或者不走完。对于不走完这部分的步数可能为m%循环节长度,也可能为m或者循环节长度。问题就转换为长度不超过限制长度的最大连续子序列,通过dp+单调队列来解决。

 #include<bits/stdc++.h>

 using namespace std;

 typedef long long ll;
const int MOD = 1e9 + ;
const int INF = 0x3f3f3f3f;
const int maxn = 1e4 + ; int n, m, k;
ll s, ans, val[maxn];
vector<ll>vec;
bool vis[maxn];
ll sum[maxn << ];
ll que[maxn << ]; inline ll cal(int count)
{
int len = vec.size();
for (int i = ; i < len; ++i)
{
que[i] = que[i + len] = vec[i];
}
len <<= ;
list<ll>q;
int st = ;
int ed = ;
ll res = ;
for (int i = ; i < len; ++i)
{
if (i == )
{
sum[i] = que[i];
}
else
{
sum[i] = sum[i - ] + que[i];
}
}
for (int i = ; i < len; ++i)
{
while (!q.empty() && sum[q.front()] > sum[i])
{
q.pop_front();
}
q.push_front(i);
while (!q.empty() && i - q.back() > count)
{
q.pop_back();
}
res = max(res, sum[i] - sum[q.back()]);
}
return res;
} inline ll solve()
{
ll mod = m % vec.size();
ll circle = m / vec.size();
ll sum = ;
for (auto it : vec)
{
sum += it;
}
ll max1 = cal(mod);
ll max2 = cal(vec.size());
max1 += max(0ll, sum) * circle;
max2 += max(0LL, sum)*((circle > ) ? circle - : );
return max(max1, max2);
} inline void RUN()
{
int t;
scanf("%d", &t);
for (int cas = ; cas <= t; ++cas)
{
memset(vis, false, sizeof vis);
scanf("%d %lld %d %d", &n, &s, &m, &k);
for (int i = ; i < n; ++i)
{
scanf("%lld", val + i);
}
ans = ;
for (int i = ; i < n; ++i)
{
if (!vis[i])
{
vec.clear();
vis[i] = true;
vec.push_back(val[i]);
for (int j = (i + k) % n; j != i && !vis[j]; j = (j + k) % n)
{
vis[j] = true;
vec.push_back(val[j]);
}
ans = max(ans, solve());
}
}
if (ans >= s) ans = ;
else ans = s - ans;
printf("Case #%d: %lld\n", cas, ans);
}
} int main()
{
#ifdef LOCAL_JUDGE
freopen("Text.txt", "r", stdin);
#endif // LOCAL_JUDGE RUN(); #ifdef LOCAL_JUDGE
fclose(stdin);
#endif // LOCAL_JUDGE return ;
}

H - Search for Answer

留坑。

I - Tree and Permutation

题意:一个序列的值为第一个点走到后面n-1个点的距离和,求n!个序列的和

思路:对于每条边,这条边的左右端点均要走向对方。那么对于每条边的经过的次数为左右端点节点数的乘积。但是每个点都作为起点(n-1)!次,求和即可得到答案。

 #include<bits/stdc++.h>

 using namespace std;

 typedef long long ll;
const int INF = 0x3f3f3f3f;
const ll INFLL = 0x3f3f3f3f3f3f3f3f;
const int MOD = (int)1e9 + ;
const int maxn = (int)1e5 + ; struct Edge {
int u, v;
ll w;
inline Edge() { }
inline Edge(int u,int v,ll w):u(u),v(v),w(w){}
}; int n;
ll ans;
int son[maxn];
vector<Edge>G[maxn]; inline void Init()
{
ans = ;
memset(son, , sizeof son);
for (int i = ; i <= n; ++i)
{
G[i].clear();
}
} inline void DFS(int u, int pre)
{
son[u] = ;
for (auto it : G[u])
{
int v = it.v;
if (v == pre) continue;
DFS(v, u);
son[u] += son[v];
ans = (ans + (ll)son[v] * (n - son[v]) % MOD * it.w) % MOD;
}
} inline void RUN()
{
while (~scanf("%d", &n))
{
Init();
for (int i = ; i < n; ++i)
{
int u, v;
ll w;
scanf("%d %d %lld", &u, &v, &w);
G[u].push_back(Edge(u, v, w));
G[v].push_back(Edge(v, u, w));
}
DFS(, -);
for (int i = ; i <= n - ; ++i)
{
ans = (ans * i) % MOD;
}
ans = (ans * ) % MOD;
printf("%lld\n", ans);
}
} int main()
{
#ifdef LOCAL_JUDGE
freopen("Text.txt", "r", stdin);
#endif // LOCAL_JUDGE RUN(); #ifdef LOCAL_JUDGE
fclose(stdin);
#endif // LOCAL_JUDGE
return ;
}

J - YJJ's Salesman

题意:给出若干个点 ,范围属于(0, 0) - (1e9, 1e9) 从(0, 0)  走到(1e9, 1e9),只能向上走,向右走,或者右上角走,有些点有权值,不能回头,求最后获得的最大权值

思路:最大上升子序列的权值和 先按x排序,再对y离散化,线段树优化

 #include <bits/stdc++.h>
using namespace std; #define N 100010 int t, n, m;
int tmp[N]; struct Data
{
int x, y, v;
inline void scan()
{
scanf("%d%d%d", &x, &y, &v);
}
inline bool operator < (const Data &r) const
{
return x < r.x || x == r.x && y < r.y;
}
}arr[N]; inline void Init()
{
for (int i = ; i <= n; ++i) tmp[i] = arr[i].y;
sort(tmp + , tmp + + n);
m = unique(tmp + , tmp + + n) - tmp - ;
} inline int Get(int x)
{
return lower_bound(tmp + , tmp + + m, x) - tmp;
} struct node
{
int l, r;
int Max;
inline node() {}
inline node(int l, int r, int Max) : l(l), r(r), Max(Max) {}
}tree[N << ]; inline void pushup(int id)
{
tree[id].Max = max(tree[id << ].Max, tree[id << | ].Max);
} inline void build(int id, int l, int r)
{
tree[id] = node(l, r, );
if (l == r) return;
int mid = (l + r) >> ;
build(id << , l, mid);
build(id << | , mid + , r);
} inline void update(int id, int pos, int val)
{
if (tree[id].l == tree[id].r)
{
tree[id].Max = max(tree[id].Max, val);
return;
}
int mid = (tree[id].l + tree[id].r) >> ;
if (pos <= mid) update(id << , pos, val);
else update(id << | , pos, val);
pushup(id);
} int ansMax; inline void query(int id, int l, int r)
{
if (l > r) return;
if (tree[id].l >= l && tree[id].r <= r)
{
ansMax = max(ansMax, tree[id].Max);
return;
}
int mid = (tree[id].l + tree[id].r) >> ;
if (l <= mid) query(id << , l, r);
if (r > mid) query(id << | , l, r);
} inline void Run()
{
scanf("%d", &t);
while (t--)
{
scanf("%d", &n);
for (int i = ; i <= n; ++i) arr[i].scan();
sort(arr + , arr + + n); Init(); build(, , n);
for (int i = ; i <= n; ++i) arr[i].y = Get(arr[i].y);
vector <int> v;
int ans = arr[].v; v.push_back();
for (int i = ; i <= n; ++i)
{
if (arr[i].x != arr[i - ].x)
{
for (auto it : v)
{
update(, arr[it].y, arr[it].v);
}
v.clear();
}
ansMax = ; query(, , arr[i].y - );
ans = max(ans, ansMax + arr[i].v);
//printf("%d %d %d\n", i, ansMax, arr[i].v);
arr[i].v += ansMax;
v.push_back(i);
}
printf("%d\n", ans);
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run(); return ;
}

2018中国大学生程序设计竞赛 - 网络选拔赛 Solution的更多相关文章

  1. 2018中国大学生程序设计竞赛 - 网络选拔赛 1001 - Buy and Resell 【优先队列维护最小堆+贪心】

    题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6438 Buy and Resell Time Limit: 2000/1000 MS (Java/O ...

  2. 2018中国大学生程序设计竞赛 - 网络选拔赛 1010 YJJ's Salesman 【离散化+树状数组维护区间最大值】

    题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6447 YJJ's Salesman Time Limit: 4000/2000 MS (Java/O ...

  3. 2018中国大学生程序设计竞赛 - 网络选拔赛 1009 - Tree and Permutation 【dfs+树上两点距离和】

    Tree and Permutation Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Oth ...

  4. 2018中国大学生程序设计竞赛 - 网络选拔赛 hdu 6440 Dream 模拟

    Dream Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Subm ...

  5. HDU - 6440 Dream 2018中国大学生程序设计竞赛 - 网络选拔赛

    给定的\(p\)是素数,要求给定一个加法运算表和乘法运算表,使\((m+n)^p = m^p +n^p(0 \leq m,n < p)\). 因为给定的p是素数,根据费马小定理得 \((m+n) ...

  6. 2018中国大学生程序设计竞赛 - 网络选拔赛 Dream hdu6440 Dream 给出一个(流氓)构造法

    http://acm.hdu.edu.cn/showproblem.php?pid=6440 题意:让你重新定义任意一对数的乘法和加法结果(输出乘法口诀表和加法口诀表),使得m^p+n^p==(m+n ...

  7. hdu6444 2018中国大学生程序设计竞赛 - 网络选拔赛 1007 Neko's loop

    Neko's loop Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total S ...

  8. 2018中国大学生程序设计竞赛 - 网络选拔赛 4 - Find Integer 【费马大定理+构造勾股数】

    Find Integer Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Tota ...

  9. 2018中国大学生程序设计竞赛 - 网络选拔赛 hdu6438 Buy and Resell 买入卖出问题 贪心

    Buy and Resell Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)To ...

随机推荐

  1. shell基础篇(四)算术运算

    ---内容来源于http://www.jb51.net/article/31232.htm shell中的赋值和操作默认都是字符串处理,1.错误方法举例 a) var=1+1 echo $var 输出 ...

  2. [置顶] think in java interview-高级开发人员面试宝典代码示例

    下载资源地址为: http://download.csdn.net/detail/lifetragedy/6379755 这是think in java interview中的代码示例,包括JAVA基 ...

  3. 深入浅出Docker(六):像谷歌一样部署你的应用

    1.概述 谷歌发起的开源项目从来都是广受技术圈的关注和讨论,本文将介绍的就是最新的容器编排管理系统Kubernetes.Kubernetes开源项目版本更新频繁,对于初次使用者来说其定义大量的技术术语 ...

  4. 开源的PaaS方案:在OpenStack上部署CloudFoundry (五)常见问题

    部署CloudFoundry可能遇到的问题 1. Bosh 报告 OpenStack API Request Entity Too Large error 解决办法,修改/etc/nova/api-p ...

  5. Android内存优化总结【整理】

    http://blog.csdn.net/tiantangrenjian/article/details/39182293 [前段时间接到任务着手进行app的内存优化,从各种各样的渠道搜索相关资料,最 ...

  6. postgresql数据库中对重复数据的处理

    我们在使用postgresql数据库的时候,如果一张数据表在未做任何约束的情况下,很可能会出现几条完全一样的数据,即重复数据.如下图所示: 那么如果我们要删除其中的2条该怎么办呢?第一种我们可以清空表 ...

  7. java GC工作机制

    转自:http://www.cnblogs.com/hzdtf/articles/5419987.html GC:垃圾回收站,是将java的无用的堆对象进行清理,释放内存,以免发生内存泄露.在介绍ja ...

  8. oneThink发生错误,获取当前执行的SQL语句!

    echo D('AnswerInfoView')->getLastSql();die();

  9. [Gradle] 查看项目依赖

    查看项目的编译依赖 $ ./gradlew :app:dependencies --configuration compile 查看具体某个库的依赖 $ ./gradlew -q :app:depen ...

  10. instanceof 用于确定一个 PHP 变量是否属于某一类 class 的实例 , 返回true或者false

    <?phpclass MyClass{} class NotMyClass{}$a = new MyClass; var_dump($a instanceof MyClass);var_dump ...