A - Problem A.Alkane

留坑。

B - Problem B. Beads

留坑。

C - Problem C. Calculate

留坑。

D - Problem D. Permutation

留坑。

E - Problem E. TeaTree

题意:每个点会存下任意两个以他为LCA的点对的GCD,求每个点存的GCD的最大值

思路:DSU on tree  用 set 维护子树中的因子,对于重儿子不要处理多次 每次查找的时候,枚举轻儿子中的因子

还有一种线段树合并的写法

 #include <bits/stdc++.h>
using namespace std; #define N 100010 int n;
vector <int> G[N], num[N];
set <int> s;
int sz[N], son[N], cnt[N], cnt2[N], arr[N], ans[N], Max;
bool isbig[N]; void Init()
{
for (int i = ; i <= ; ++i)
{
int limit = sqrt(i);
for (int j = ; j < limit; ++j) if (i % j == )
{
num[i].push_back(j);
num[i].push_back(i / j);
}
if (i % limit == )
{
num[i].push_back(limit);
if (limit * limit != i) num[i].push_back(i / limit);
}
}
} void DFS(int u)
{
sz[u] = ;
for (auto v : G[u])
{
DFS(v); sz[u] += sz[v];
if (son[u] == - || sz[v] > sz[son[u]]) son[u] = v;
}
} void update(int u)
{
for (auto it : num[arr[u]]) ++cnt[it];
for (auto v : G[u]) if (!isbig[v]) update(v);
} void work(int u, int fa)
{
for (auto it : num[arr[u]]) s.insert(it);
for (auto v : G[u]) if (!isbig[v]) work(v, fa);
} void query(int u)
{
for (auto v : G[u]) if (!isbig[v])
{
s.clear();
work(v, u);
for (auto it : s) if (cnt[it] >= || cnt2[it] >= ) Max = max(Max, it);
for (auto it : s) ++cnt2[it];
}
for (auto it : num[arr[u]]) if (cnt[it] >= || cnt2[it] >= ) Max = max(Max, it);
} void clear(int u)
{
for (auto it : num[arr[u]]) cnt[it] = cnt2[it] = ;
for (auto v : G[u]) clear(v);
} void DSU(int u)
{
for (auto v : G[u]) if (v != son[u]) DSU(v);
if (son[u] != -) { isbig[son[u]] = ; DSU(son[u]); }
Max = -; query(u);
ans[u] = Max;
if (isbig[u]) update(u);
if (son[u] != -) isbig[son[u]] = ;
if (!isbig[u]) clear(u);
} int main()
{
Init();
while (scanf("%d", &n) != EOF)
{
for (int i = ; i <= n; ++i) G[i].clear();
memset(son, -, sizeof son);
memset(cnt, , sizeof cnt);
memset(cnt2, , sizeof cnt2);
Max = -; s.clear();
for (int i = , u; i <= n; ++i)
{
scanf("%d", &u);
G[u].push_back(i);
}
for (int i = ; i <= n; ++i) scanf("%d", arr + i);
DFS(); DSU();
for (int i = ; i <= n; ++i) printf("%d\n", ans[i]);
}
return ;
}
 #include <bits/stdc++.h>
using namespace std; #define N 100010
vector <int> num[N], G[N]; int n;
int arr[N], rt[N], ans[N]; void Init()
{
for (int i = ; i <= ; ++i) for (int j = i; j <= ; j += i)
num[j].push_back(i);
} struct SEG
{
#define M N * 400
int lson[M], rson[M], c[M], cnt;
void init() { cnt = ; }
void pushup(int id) { c[id] = max(c[lson[id]], c[rson[id]]); }
void update(int &x, int l, int r, int pos)
{
if (!x) x = ++cnt;
if (l == r) { c[x] = pos; return; }
int mid = (l + r) >> ;
pos <= mid ? update(lson[x], l, mid, pos) : update(rson[x], mid + , r, pos);
pushup(x);
}
int merge(int u, int v, int &sum)
{
if (!u || !v) return u | v;
if (c[u] == c[v]) sum = max(sum, c[u]);
if (lson[u] | lson[v]) lson[u] = merge(lson[u], lson[v], sum);
if (rson[u] | rson[v]) rson[u] = merge(rson[u], rson[v], sum);
return u;
}
}seg; void DFS(int u)
{
ans[u] = -;
for (auto v : G[u])
{
DFS(v);
seg.merge(rt[u], rt[v], ans[u]);
}
} void Run()
{
Init();
while (scanf("%d", &n) != EOF)
{
seg.init();
for (int i = , u; i <= n; ++i)
{
scanf("%d", &u);
G[u].push_back(i);
}
for (int i = ; i <= n; ++i) scanf("%d", arr + i);
for (int i = ; i <= n; ++i) for (auto it : num[arr[i]]) seg.update(rt[i], , , it);
DFS();
for (int i = ; i <= n; ++i) printf("%d\n", ans[i]);
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ; }

F - Problem F. NewNippori

留坑。

G - Problem G. Cyclic

打表找规律即可

$F[n] = (n - 2) * F[n - 1] + (n - 1) * F[n - 2] + (i \& 1 ? 1 : -1)$

 #include <bits/stdc++.h>
using namespace std; #define N 100010
#define ll long long const ll MOD = ; ll arr[N]; int main()
{
arr[] = , arr[] = ;
for (int i = ; i <= ; ++i) arr[i] = ((i - ) * arr[i - ] % MOD + (i - ) * arr[i - ] % MOD + ((i & ) ? : -) + MOD) % MOD;
int t; scanf("%d", &t);
while (t--)
{
int n;
scanf("%d", &n);
printf("%lld\n", arr[n]);
}
}

H - Problem H. Pow

水。

import java.util.Scanner;
import java.math.*; public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int t = in.nextInt();
while (t-- != 0)
{
int n = in.nextInt();
System.out.println(BigInteger.valueOf(2).pow(n));
}
}
}

I - Problem I. Count

题意:求$\sum_{i = 1} ^ {i = n} \sum_{j = 1} ^ {j = i - 1} [gcd(i + j, i - j) == 1]$

思路:找规律。如果是奇数就加上$\frac {\varphi(n)}{2}   否则加上 \varphi(n)$

 #include <bits/stdc++.h>

 using namespace std;

 typedef long long ll;
const int MAXN = ;
bool check[MAXN + ]; ll ans[MAXN + ];
int phi[MAXN + ];
int prime[MAXN + ];
int tot; void phi_ans_prime_table() {
memset(check, false, sizeof check);
phi[] = ;
tot = ;
for(int i = ; i <= MAXN; ++i)
{
if(!check[i])
{
prime[tot++] = i;
phi[i] = i - ;
}
for(int j = ; j < tot; ++j)
{
if(i * prime[j] > MAXN) break;
check[i * prime[j]] = true;
if(i % prime[j] == )
{
phi[i * prime[j]] = phi[i] * prime[j];
break;
}
else
{
phi[i * prime[j]] = phi[i] * (prime[j] - );
}
}
if(i & ) ans[i] = ans[i - ] + phi[i] / ;
else ans[i] = ans[i - ] + phi[i];
}
} int main() {
phi_ans_prime_table();
int t;
scanf("%d", &t);
while(t--)
{
int n;
scanf("%d", &n);
printf("%lld\n", ans[n]);
}
return ;
}

J - Problem J. CSGO

题意:有n把主武器和m把副武器,每把武器有k种属性,选取一把主武器和副武器,求题中式子最大值

思路:对于没种属性又有加减两种状态,枚举每把武器的每种属性的加减状态,求最大值

 #include<bits/stdc++.h>

 using namespace std;

 typedef long long ll;

 const ll INFLL = 0x3f3f3f3f3f3f3f3f;
const int maxn = 1e5 + ; ll arr[maxn][], brr[maxn][];
ll crr[maxn]; int n, m, k; void RUN()
{
int t;
scanf("%d", &t);
while (t--)
{
scanf("%d %d %d", &n, &m, &k);
for (int i = ; i <= n; ++i) for (int j = ; j <= k; ++j) scanf("%lld", &arr[i][j]);
for (int i = ; i <= m; ++i) for (int j = ; j <= k; ++j) scanf("%lld", &brr[i][j]);
memset(crr, , sizeof crr);
ll ans = ;
int limit = ( << k);
for (int i = ; i <= n; ++i)
{
for (int S = ; S < limit; ++S)
{
ll tmp = arr[i][];
for (int j = ; j < k; ++j)
{
if (S & ( << j))
{
tmp += arr[i][j + ];
}
else
{
tmp -= arr[i][j + ];
}
}
crr[S] = max(crr[S], tmp);
}
} for (int i = ; i <= m; ++i)
{
for (int S = ; S < limit; ++S)
{
ll tmp = brr[i][];
for (int j = ; j < k; ++j)
{
if (S & ( << j))
{
tmp += brr[i][j + ];
}
else
{
tmp -= brr[i][j + ];
}
}
ans = max(ans, tmp + crr[limit - - S]);
}
}
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 ;
}
#include <bits/stdc++.h>
using namespace std; #define N 100010
#define ll long long
#define INF 0x3f3f3f3f3f3f3f3f int t, n, m, K; struct node
{
int x[];
void scan(int vis)
{
scanf("%d", x + vis);
for (int i = ; i <= K + ; ++i) scanf("%d", x + i);
}
}a[N], b[N]; void Run()
{
scanf("%d", &t);
while (t--)
{
scanf("%d%d%d", &n, &m, &K);
for (int i = ; i <= n; ++i) a[i].scan();
for (int i = ; i <= m; ++i) b[i].scan();
ll res = ;
for (int i = ; i < ( << (K + )); ++i)
{
bitset <> bit; bit = i;
ll Max[] = { -INF, -INF };
ll Min[] = { INF, INF };
for (int j = ; j <= n; ++j)
{
ll tmp = ;
for (int k = ; k <= K + ; ++k)
tmp += a[j].x[k] * (bit[k] ? : -);
Max[] = max(Max[], tmp);
Min[] = min(Min[], tmp);
}
for (int j = ; j <= m; ++j)
{
ll tmp = ;
for (int k = ; k <= K + ; ++k)
tmp += b[j].x[k] * (bit[k] ? : -);
Max[] = max(Max[], tmp);
Min[] = min(Min[], tmp);
}
res = max(res, max(Max[] - Min[], Max[] - Min[]));
}
printf("%lld\n", res);
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ; }

K - Problem K. Pow2

留坑。

L - Problem L.Videos

题意:每天有n个小时,有m部电影,k个人,每部电影只能被一个人看,得到w快乐值,电影种类有AB两种,同一人连着看同种电影要减去W快乐值,如何安排使得快乐值最大

思路:将一部电影拆成两个点 S 和 T 流为1,费用为-w, 电影与电影之间如果是可以连着看的,就连边,如果是同种类,费用就是W, 否则就是0,流为1,源点练出来加一个点,流量为k,限制为k个人

 #include<bits/stdc++.h>

 using namespace std;

 const int INF = 0x3f3f3f3f;
const int maxn = 1e4 + ;
const int maxm = 1e5 + ; struct Edge{
int to, nxt, cap, flow, cost;
}edge[maxm]; int head[maxn], tot;
int pre[maxn], dis[maxn];
bool vis[maxn];
int N; void Init(int n)
{
N = n;
tot = ;
for(int i = ; i < n; ++i) head[i] = -;
} void addedge(int u, int v, int cap, int cost)
{
edge[tot].to = v;
edge[tot].cap = cap;
edge[tot].cost = cost;
edge[tot].flow = ;
edge[tot].nxt = head[u];
head[u] = tot++; edge[tot].to = u;
edge[tot].cap = ;
edge[tot].cost = -cost;
edge[tot].flow = ;
edge[tot].nxt = head[v];
head[v] = tot++;
} bool SPFA(int s,int t)
{
queue<int>q;
for(int i = ; i < N; ++i) dis[i] = INF, pre[i] = -, vis[i] = false;
dis[s] = ;
vis[s] = true;
q.push(s);
while(!q.empty())
{
int u = q.front();
q.pop();
vis[u] = false;
for(int i = head[u]; ~i; i = edge[i].nxt)
{
int v = edge[i].to;
if(edge[i].cap > edge[i].flow && dis[v] > dis[u] + edge[i].cost)
{
dis[v] = dis[u] + edge[i].cost;
pre[v] = i;
if(!vis[v])
{
vis[v] = true;
q.push(v);
}
}
}
}
if(pre[t] == -) return false;
else return true;
} int minCostMaxflow(int s,int t, int &cost)
{
int flow = ;
cost = ;
while(SPFA(s, t))
{
int Min = INF;
for(int i = pre[t]; ~i; i = pre[edge[i ^ ].to])
{
if(Min > edge[i].cap - edge[i].flow)
{
Min = edge[i].cap - edge[i].flow;
}
}
for(int i = pre[t]; ~i; i = pre[edge[i ^ ].to])
{
edge[i].flow += Min;
edge[i ^ ].flow -= Min;
cost += edge[i].cost * Min;
}
flow += Min;
}
return flow;
} struct node{
int si, ti, wi, op;
}arr[maxn]; int n, m, K, W; int main()
{
int t;
scanf("%d", &t);
while(t--)
{
scanf("%d %d %d %d", &n, &m, &K, &W);
for(int i = ; i <= m; ++i) scanf("%d %d %d %d", &arr[i].si, &arr[i].ti, &arr[i].wi, &arr[i].op);
Init( * m + );
addedge(, * m + , K, );
for(int i = ; i <= m; ++i) addedge( * m + , * i - , , );
for(int i = ; i <= m; ++i) addedge( * i - , * i, , -arr[i].wi);
for(int i = ; i <= m; ++i) addedge( * i, * m + , , );
for(int i = ; i <= m; ++i)
{
for(int j = ; j <= m; ++j)
{
if(i == j) continue;
if(arr[i].ti <= arr[j].si)
{
if(arr[i].op == arr[j].op)
{
addedge( * i, * j - , , W);
}
else
{
addedge( * i, * j - , , );
}
}
}
}
int cost = ;
minCostMaxflow(, * m + , cost);
printf("%d\n", -cost);
}
return ;
}

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

  1. 2018 Nowcoder Multi-University Training Contest 10

    Practice Link J. Rikka with Nickname 题意: 给出\(n\)个字符串,要求依次合并两个串\(s, t\),满足将\(t\)合并到\(s\)中变成\(r\),使得\( ...

  2. 2016 Multi-University Training Contest 10

    solved 7/11 2016 Multi-University Training Contest 10 题解链接 分类讨论 1001 Median(BH) 题意: 有长度为n排好序的序列,给两段子 ...

  3. hdu 5416 CRB and Tree(2015 Multi-University Training Contest 10)

    CRB and Tree                                                             Time Limit: 8000/4000 MS (J ...

  4. 2015 Multi-University Training Contest 10 hdu 5406 CRB and Apple

    CRB and Apple Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)To ...

  5. 2015 Multi-University Training Contest 10 hdu 5412 CRB and Queries

    CRB and Queries Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Other ...

  6. [二分,multiset] 2019 Multi-University Training Contest 10 Welcome Party

    Welcome Party Time Limit: 4000/4000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)T ...

  7. 2015 Multi-University Training Contest 10(9/11)

    2015 Multi-University Training Contest 10 5406 CRB and Apple 1.排序之后费用流 spfa用stack才能过 //#pragma GCC o ...

  8. 2018 Multi-University Training Contest 5 Solution

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

  9. 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, ...

随机推荐

  1. ios 获取设备相关的信息

    .获取设备的信息 UIDevice *device = [[UIDevice alloc] int]; NSString *name = device.name; //获取设备所有者的名称 NSStr ...

  2. NPOI抓取WPS表格保存的EXCEL文件

    其实是可以抓取的,唯一不同就是Sheet的位置前进了一位.     var sheet1 = (HSSFSheet)hssfworkbook.GetSheetAt(1);     来自为知笔记(Wiz ...

  3. PHP读取远程文件的三种方法

    file_get_contents <?php$url = http://www.xxx.com/;$contents = file_get_contents($url);//如果出现中文乱码使 ...

  4. JavaScript中eval()函数

    eval调用时,实例为eval( "( javascript代码 )" ), eval() 函数可将字符串转换为代码执行,并返回一个或多个值.

  5. linux 下 git gem 等代理设置问题

    github.com,作为程序员的代码仓库,我们经常会用到.但有时候我们不能直接通过网络链接它,只能通过代理. 这里我有一台代理服务器,起初我以为在终端设置了代理环境就行了,其设置为在你的~/.bas ...

  6. CSS-项目中遇到IE兼容问题,处理随笔

    总是忘记给ie做特殊样式处理,以前打游击,不做也就算了,以后可不行,得对自己的“孩子”负责.. 一.先说IE老大的兼容 知道了一些常用的css属性兼容方法确实可以解决问题, 但我不知道我自己的ieTe ...

  7. redis未授权访问漏洞那拿SHELL

    一.什么是redis未授权访问漏洞: 1.redis是一种文档型数据库,快速高效,存储在内存中,定期才会写磁盘.主要用于快速缓存,数据转存处理等.默认redis开在6379端口,可以直接访问.并不需要 ...

  8. 【BZOJ2164】采矿 树链剖分+线段树维护DP

    [BZOJ2164]采矿 Description 浩浩荡荡的cg大军发现了一座矿产资源极其丰富的城市,他们打算在这座城市实施新的采矿战略.这个城市可以看成一棵有n个节点的有根树,我们把每个节点用1到n ...

  9. 【BZOJ5008】方师傅的房子 三角剖分

    [BZOJ5008]方师傅的房子 Description 方师傅来到了一个二维平面.他站在原点上,觉得这里风景不错,就建了一个房子.这个房子是n个点的凸多边形,原点一定严格在凸多边形内部.有m个人也到 ...

  10. Unity3D笔记四 基础知识概念

    1. Project视图 主要存放游戏中用到的所有资源文件,常见的包括:游戏脚本.预设.材质.动画.自定义字体.纹理.物理材质和GUI皮肤等. 1>     Folder: 文件夹,用于资源的分 ...