C - Sugar Water

计算一下可以达到水是多少,可以到达的糖是多少

枚举水,然后加最多能加的糖,是\(min(F - i *100,E * 100)\),计算密度,和前一个比较就行

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define MAXN 100005
#define eps 1e-12
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
res = 0;T f = 1;char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar('-');}
if(x >= 10) {
out(x / 10);
}
putchar('0' + x % 10);
}
int A,B,C,D,E,F;
int w[35],t[3005];
void Solve() {
read(A);read(B);read(C);read(D);read(E);read(F);
w[0] = 1;
for(int i = 1 ; i <= F / 100 ; ++i) {
if(i >= A) w[i] |= w[i - A];
if(i >= B) w[i] |= w[i - B];
}
t[0] = 1;
for(int i = 1 ; i <= F ; ++i) {
if(i >= C) t[i] |= t[i - C];
if(i >= D) t[i] |= t[i - D];
}
t[0] = 0;
for(int i = 1 ; i <= F ; ++i) {
if(t[i]) t[i] = i;
else t[i] = t[i - 1];
}
int a = A * 100,b = 0;
for(int i = 1 ; i <= F / 100 ; ++i) {
if(!w[i]) continue;
int rem = min(F - i * 100,i * E);
int s = t[rem],p = i * 100 + s;
if(s * a > b * p) {a = p;b = s;}
}
out(a);space;out(b);enter;
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
}

D - Restoring Road Network

很容易发现边肯定都被涵盖在最短路的数值里(如果要构造出一个价值最小的图)

我们从小到大加边,对于一个(u,v)最短路,如果这个最短路不用额外边,那么就是用一个别的点k,(u,k) + (k,v) = (u,v)

如果算出来的最短路小于给定值,那么就不合法

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define MAXN 100005
#define eps 1e-12
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
res = 0;T f = 1;char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar('-');}
if(x >= 10) {
out(x / 10);
}
putchar('0' + x % 10);
}
int64 A[305][305];
int64 B[305][305],ans;
pii p[100005];
int tot,N;
void Solve() {
read(N);
for(int i = 1 ; i <= N ; ++i) {
for(int j = 1 ; j <= N ; ++j) {
read(A[i][j]);
if(i != j) B[i][j] = 1e16;
if(i < j) p[++tot] = mp(i,j);
}
}
sort(p + 1,p + tot + 1,[](pii a,pii b){return A[a.fi][a.se] < A[b.fi][b.se];});
for(int i = 1 ; i <= tot ; ++i) {
int u = p[i].fi,v = p[i].se;
for(int j = 1 ; j <= N ; ++j) {
B[u][v] = min(B[u][j] + B[j][v],B[u][v]);
}
B[v][u] = B[u][v];
if(B[u][v] < A[u][v]) {puts("-1");return;}
if(B[u][v] == A[u][v]) continue;
ans += A[u][v];
B[u][v] = B[v][u] = A[u][v];
}
out(ans);enter;
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
}

E - Bichrome Tree

我们希望除了和该点同色的值之外,另一种颜色的值总和尽可能的小,这样容易达成目标

可以直接做一个背包dp就行,每次尽量取最小的值当做另一种颜色的值

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define MAXN 5005
#define eps 1e-12
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
res = 0;T f = 1;char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar('-');}
if(x >= 10) {
out(x / 10);
}
putchar('0' + x % 10);
}
int N,P[MAXN],X[MAXN];
int dp[MAXN],sum[MAXN];
bool f[MAXN][MAXN];
void Solve() {
read(N);
for(int i = 2 ; i <= N ; ++i) read(P[i]);
for(int i = 1 ; i <= N ; ++i) read(X[i]);
for(int i = 1 ; i <= N ; ++i) f[i][0] = 1;
for(int i = N ; i >= 1 ; --i) {
bool flag = 0;
for(int j = X[i] ; j >= 0 ; --j) {
if(f[i][j]) {
dp[i] = sum[i] - j;
flag = 1;
break;
}
}
if(!flag) {
puts("IMPOSSIBLE");return;
}
if(P[i]) {
for(int j = X[P[i]] ; j >= 0 ; --j) {
bool t = 0;
if(j >= X[i]) t |= f[P[i]][j - X[i]];
if(j >= dp[i]) t |= f[P[i]][j - dp[i]];
f[P[i]][j] = t;
}
sum[P[i]] += X[i] + dp[i];
}
}
puts("POSSIBLE");
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
}

F - Collecting Balls

行列拆点,有一个点就行列之间连边

连出的图肯定是很多个基环外向树森林

相当于给每个点分配一个边,给环上的点分配边就两种方式,每种分别计算方案数

分配完之后每个点假如横向,这个点往横向之前所有的点连一条边

竖向同理

然后就是求一个树的dfs序个数

最后把所有联通块的答案合出来就行

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define MAXN 200005
#define eps 1e-12
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
res = 0;T f = 1;char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar('-');}
if(x >= 10) {
out(x / 10);
}
putchar('0' + x % 10);
}
const int MOD = 1000000007;
int inc(int a,int b) {
return a + b >= MOD ? a + b - MOD : a + b;
}
int mul(int a,int b) {
return 1LL * a * b % MOD;
}
int fpow(int x,int c) {
int res = 1,t = x;
while(c) {
if(c & 1) res = mul(res,t);
t = mul(t,t);
c >>= 1;
}
return res;
}
void update(int &x,int y) {
x = inc(x,y);
}
struct node {
int to,next;
}E[MAXN * 4];
int x[MAXN],y[MAXN],N,fac[MAXN],invfac[MAXN];
map<pii,int> zz;
int head[MAXN],sumE;
bool vis[MAXN];
int sum,Ncnt,fa[MAXN],s,t,pos[MAXN],par[MAXN];
vector<int> c[MAXN],r[MAXN],rec,cyc;
int rpos[MAXN],cpos[MAXN],siz[MAXN];
vector<int> son[MAXN];
void add(int u,int v) {
E[++sumE].to = v;
E[sumE].next = head[u];
head[u] = sumE;
}
pii depos(int a,int b) {
if(a > b) swap(a,b);
b -= N;
return mp(a,b);
}
bool dfs(int u) {
++Ncnt;
bool flag = 0;
vis[u] = 1;
for(int i = head[u] ; i ; i = E[i].next) {
++sum;
int v = E[i].to;
if(!vis[v]) {
fa[v] = u;
if(dfs(v)) {
flag = 1;
pos[zz[depos(u,v)]] = u;
}
}
else if(v != fa[u] && !flag){
s = u,t = v;
flag = 1;
rec.pb(zz[depos(u,v)]);
}
}
if(!flag && fa[u]) {
pos[zz[depos(u,fa[u])]] = u;
}
if(fa[u]) rec.pb(zz[depos(u,fa[u])]);
return flag;
}
int Calc(int u) {
siz[u] = 1;
int res = 1;
for(auto v : son[u]) {
res = mul(res,Calc(v));
res = mul(res,invfac[siz[v]]);
siz[u] += siz[v];
}
res = mul(res,fac[siz[u] - 1]);
return res;
}
int Process() {
int res = 0;
for(auto t : rec) par[t] = 0;
for(auto t : rec) {
if(pos[t] > N) {
for(int i = 0 ; i < cpos[t] ; ++i) {
par[zz[mp(c[y[t]][i],y[t])]] = t;
}
}
else {
for(int i = 0 ; i < rpos[t] ; ++i) {
par[zz[mp(x[t],r[x[t]][i])]] = t;
}
}
son[t].clear();
}
son[0].clear();
for(auto t : rec) {
son[par[t]].pb(t);
}
return Calc(0);
}
void Solve() {
read(N);
for(int i = 1 ; i <= 2 * N ; ++i) {
read(x[i]);read(y[i]);add(x[i],y[i] + N);add(y[i] + N,x[i]);
zz[mp(x[i],y[i])] = i;
r[x[i]].pb(y[i]);c[y[i]].pb(x[i]);
}
for(int i = 1 ; i <= N ; ++i) {
sort(r[i].begin(),r[i].end());
sort(c[i].begin(),c[i].end());
for(int j = 1 ; j < r[i].size() ; ++j) rpos[zz[mp(i,r[i][j])]] = j;
for(int j = 1 ; j < c[i].size() ; ++j) cpos[zz[mp(c[i][j],i)]] = j;
}
fac[0] = 1;
for(int i = 1 ; i <= 2 * N ; ++i) fac[i] = mul(fac[i - 1],i);
invfac[2 * N] = fpow(fac[2 * N],MOD - 2);
for(int i = 2 * N - 1 ; i >= 0 ; --i) invfac[i] = mul(invfac[i + 1],i + 1);
int ans = fac[2 * N];
for(int i = 1 ; i <= 2 * N ; ++i) {
if(!vis[i]) {
sum = 0;Ncnt = 0;
rec.clear();
dfs(i);
ans = mul(ans,invfac[Ncnt]);
if(Ncnt * 2 != sum) {puts("0");return;}
int p = s;
cyc.clear();
while(1) {
cyc.pb(p);
if(p == t) break;
p = fa[p];
}
int tmp = 0;
cyc.pb(s);
for(int i = 0 ; i < cyc.size() - 1 ; ++i) {
pos[zz[depos(cyc[i],cyc[i + 1])]] = cyc[i];
}
update(tmp,Process());
for(int i = cyc.size() - 1 ; i >= 1 ; --i) {
pos[zz[depos(cyc[i],cyc[i - 1])]] = cyc[i];
}
update(tmp,Process());
ans = mul(ans,tmp);
}
}
out(ans);enter;
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
}

【AtCoder】ARC083的更多相关文章

  1. 【Atcoder】ARC083 D - Restoring Road Network

    [算法]图论,最短路? [题意]原图为无向连通图,现给定原图的最短路矩阵,求原图最小边权和,n<=300. [题解]要求最小边权和下,原图的所有边一定是所连两端点的最短路. 那么现在将所有最短路 ...

  2. 【AtCoder】ARC092 D - Two Sequences

    [题目]AtCoder Regular Contest 092 D - Two Sequences [题意]给定n个数的数组A和数组B,求所有A[i]+B[j]的异或和(1<=i,j<=n ...

  3. 【Atcoder】CODE FESTIVAL 2017 qual A D - Four Coloring

    [题意]给定h,w,d,要求构造矩阵h*w满足任意两个曼哈顿距离为d的点都不同色,染四色. [算法]结论+矩阵变换 [题解] 曼哈顿距离是一个立着的正方形,不方便处理.d=|xi-xj|+|yi-yj ...

  4. 【AtCoder】ARC 081 E - Don't Be a Subsequence

    [题意]给定长度为n(<=2*10^5)的字符串,求最短的字典序最小的非子序列字符串. http://arc081.contest.atcoder.jp/tasks/arc081_c [算法]字 ...

  5. 【AtCoder】AGC022 F - Leftmost Ball 计数DP

    [题目]F - Leftmost Ball [题意]给定n种颜色的球各k个,每次以任意顺序排列所有球并将每种颜色最左端的球染成颜色0,求有多少种不同的颜色排列.n,k<=2000. [算法]计数 ...

  6. 【AtCoder】AGC005 F - Many Easy Problems 排列组合+NTT

    [题目]F - Many Easy Problems [题意]给定n个点的树,定义S为大小为k的点集,则f(S)为最小的包含点集S的连通块大小,求k=1~n时的所有点集f(S)的和取模92484403 ...

  7. 【AtCoder】ARC067 F - Yakiniku Restaurants 单调栈+矩阵差分

    [题目]F - Yakiniku Restaurants [题意]给定n和m,有n个饭店和m张票,给出Ai表示从饭店i到i+1的距离,给出矩阵B(i,j)表示在第i家饭店使用票j的收益,求任选起点和终 ...

  8. 【AtCoder】ARC095 E - Symmetric Grid 模拟

    [题目]E - Symmetric Grid [题意]给定n*m的小写字母矩阵,求是否能通过若干行互换和列互换使得矩阵中心对称.n,m<=12. [算法]模拟 [题解]首先行列操作独立,如果已确 ...

  9. 【Atcoder】AGC022 C - Remainder Game 搜索

    [题目]C - Remainder Game [题意]给定n个数字的序列A,每次可以选择一个数字k并选择一些数字对k取模,花费2^k的代价.要求最终变成序列B,求最小代价或无解.n<=50,0& ...

随机推荐

  1. Docker 入门 第六部分:部署app

    目录 Docker 入门 第六部分:部署app 先决条件 介绍 选择一个选项 Docker CE(Cloud provider) Enterprise(Cloud provider)这里不做介绍 En ...

  2. 浅谈分词算法(4)基于字的分词方法(CRF)

    目录 前言 目录 条件随机场(conditional random field CRF) 核心点 线性链条件随机场 简化形式 CRF分词 CRF VS HMM 代码实现 训练代码 实验结果 参考文献 ...

  3. 基于Redis主从复制读写分离架构的Session共享(Windows Server)

    搭建主从复制 1.安装软件 下载Redis-x64-3.2.100.zip:https://github.com/MicrosoftArchive/redis/releases 第一步:将Redis拷 ...

  4. mac系统如何在桌面新建文件(夹)

    方法一:(终端方式,推荐) 1.在电脑上找到终端 2.指定你想要保存文件的路径,然后回车.例如桌面就是: cd desktop #或是 cd /Users/username/Desktop 有人问:假 ...

  5. luogu P4074 [WC2013]糖果公园

    传送门 这种题显然要用树上莫队 何为树上莫队?就是在树上跑莫队算法就是先把树分块,然后把询问离线,按照左端点所在块为第一关键字,右端点所在块为第二关键字,时间戳(如果有修改操作)为第三关键字排序,然后 ...

  6. 第19月第2天 cellForItemAtIndexPath 返回空

    1. 动画需要获取当前的 Cell ,下面的调用在 viewDidLoad 中,有时候返回 nil,有时候成功. UICollectionView *cell = (UICollectionView* ...

  7. 2017-2018-2 20155303『网络对抗技术』Final:Web渗透获取WebShell权限

    2017-2018-2 『网络对抗技术』Final:Web渗透获取WebShell权限 --------CONTENTS-------- 一.Webshell原理 1.什么是WebShell 2.We ...

  8. iptables学习笔记_____摘自朱双印个人日志 ____http://www.zsythink.net/

    iptables为我们预先定义了四张表 raw.mangle.nat.filter filter表负责过滤:允许那些ip访问.拒绝那些ip访问.允许那些端口...是最常用的表 #查看表里面所有的规则i ...

  9. 用C++的 new 代替 C 的 malloc 进行内存分配

    例子: (int*)malloc(100*sizeof(int)) 是先取得int类型的字节宽度,然后乘100计算后得到400,然后调用malloc,并将400传递给函数,分配400字节的内存空间,但 ...

  10. 关于python中的module

    python中的module(模块),关于这个概念以及使用时主要有以下几点需要注意: (1)import xx时,会首先将这个xx module中的代码执行一遍(且仅执行一遍): 例如: (2)模块包 ...