Cqoi2017试题泛做
Day1
4813: [Cqoi2017]小Q的棋盘
树形背包DP。
#include <cstdio> #define maxn 110
#define R register
#define cmax(_a, _b) (_a < (_b) ? _a = (_b) : 0)
struct Edge {
Edge *next;
int to;
} *last[maxn], e[maxn << ], *ecnt = e;
inline void link(R int a, R int b)
{
*++ecnt = (Edge) {last[a], b}; last[a] = ecnt;
*++ecnt = (Edge) {last[b], a}; last[b] = ecnt;
}
int f1[maxn][maxn], f2[maxn][maxn], m;
bool vis[maxn];
void dfs(R int x)
{
vis[x] = ;
for (R int i = ; i <= m; ++i) f1[x][i] = f2[x][i] = ;
for (R Edge *iter = last[x]; iter; iter = iter -> next)
if (!vis[iter -> to])
{
dfs(iter -> to);
for (R int j = m; j; --j)
for (R int k = ; k < j; ++k)
{
cmax(f1[x][j], f2[x][j - k - ] + f1[iter -> to][k]);
k != j - ? cmax(f1[x][j], f1[x][j - k - ] + f2[iter -> to][k]) : ;
}
for (R int j = m; j >= ; --j)
for (R int k = ; k < j - ; ++k)
cmax(f2[x][j], f2[x][j - k - ] + f2[iter -> to][k]);
}
}
int main()
{
R int n; scanf("%d%d", &n, &m);
for (R int i = ; i < n; ++i) {R int a, b; scanf("%d%d", &a, &b); link(a, b);}
dfs();
R int ans = ;
for (R int i = ; i <= m; ++i) cmax(ans, f1[][i]), cmax(ans, f2[][i]);
printf("%d\n", ans);
return ;
}
D1T1
4814: [Cqoi2017]小Q的草稿
暂时还没做。marked。
4815: [Cqoi2017]小Q的表格
做完发现自己推式子和推结论的能力不足。这题有一个结论是只和对角线上的元素的权值有关,并且f[a,b]可以写成k*a*b的形式(这个结论我也是网上看的,但是我向BZOJ要的数据里这个条件并不满足,如果直接将题目给你的x/a/b得到的不会是一个整数,而把x/a/b改成模意义下x*a^(-1)*b^(-1)居然就能过了)。然后推出来是∑f[d]*∑∑(i*j*[gcd(i,j)==d]),然后还有一个结论是
∑i*[gcd(i,n)==1]=phi(n)*n/2。如果知道这两个结论应该剩下就只剩套路了(?)。设g[n] = ∑∑(i*j*[gcd(i,j)==1], 1<=i,j<=n),答案变成求∑f[d]*g[k/d]。然后k/d是根号分段的,根号枚举一下然后动态地求前缀和。前缀和这里用分块来实现根号修改O1查询。总的复杂度O(n+m√n)。
#include <cstdio>
#include <cmath> #define R register
#define maxn 4000010
#define maxs 2333
typedef long long ll;
const int mod = 1e9 + ;
int pr[maxn], prcnt, phi[maxn], g[maxn], f[maxn];
int sum[maxn], ssum[maxs];
bool vis[maxn];
inline int qpow(R int base, R int power)
{
R int ret = ;
for (; power; power >>= , base = 1ll * base * base % mod)
power & ? ret = 1ll * ret * base % mod : ;
return ret;
}
int gcd(R int a, R int b)
{
return !b ? a : gcd(b, a % b);
}
int main()
{
R int m, n; scanf("%d%d", &m, &n);
phi[] = ; g[] = ; f[] = ;
for (R int i = ; i <= n; ++i)
{
if (!vis[i]) pr[++prcnt] = i, phi[i] = i - ;
g[i] = (g[i - ] + 1ll * i * i % mod * phi[i]) % mod;
f[i] = 1ll * i * i % mod;
for (R int j = ; j <= prcnt && 1ll * pr[j] * i <= n; ++j)
{
vis[i * pr[j]] = ;
if (i % pr[j] == )
{
phi[i * pr[j]] = phi[i] * pr[j];
break;
}
else phi[i * pr[j]] = phi[i] * phi[pr[j]];
}
}
R int size = sqrt(n), tot = n / size + ;
// printf("\nsize%d\n", size);
for (R int i = ; i <= n; ++i)
if (i % size == ) ssum[i / size] = (ssum[i / size - ] + sum[i - ]) % mod, sum[i] = f[i];
else sum[i] = (sum[i - ] + f[i]) % mod;
// for (R int i = 1; i <= n; ++i) printf("%d ", sum[i]); puts("");
for (; m; --m)
{
R int a, b, k, d; R ll x;
scanf("%d%d%lld%d", &a, &b, &x, &k);
// if (x % a != 0 || x % b != 0) puts("WA"), printf("%lld %d %d %d\n", x, a, b, m);
x %= mod;
// printf("kk %lld\n", kk);
f[d = gcd(a, b)] = 1ll * x * qpow(1ll * a * b % mod, mod - ) % mod * d % mod * d % mod;
R int spos = d / size + ;
for (R int i = d; i < spos * size; ++i) sum[i] = ((i % size == ? : sum[i - ]) + f[i]) % mod;
for (R int i = spos; i <= tot; ++i) ssum[i] = (ssum[i - ] + sum[i * size - ]) % mod;
// for (R int i = 1; i <= n; ++i) printf("%d ", sum[i]); puts("");
R int ans = ;
#define query(x) (sum[(x)] + ssum[(x) / size])
for (R int i = , j; i <= k; i = j + )
{
j = k / (k / i);
ans = (ans + 1ll * (query(j) % mod - query(i - ) % mod + mod) % mod * g[k / i]) % mod;
}
printf("%d\n", ans);
}
return ;
}
D1T3
Day2
4822: [Cqoi2017]老C的任务
挺裸的二维数点问题。扫描线+树状数组简单维护即可。(将一个询问拆成几个前缀询问加加减减的形式)
#include <cstdio>
#include <algorithm> #define R register
#define lowbit(_x) ((_x) & -(_x))
#define maxn 100010
struct Event {
int type, id, x, l, r;
inline bool operator < (const Event &that) const {return x < that.x || (x == that.x && type < that.type);}
} p[maxn << ];
int hash[maxn << ], hcnt, pcnt;
typedef long long ll;
ll b[maxn << ], ans[maxn];
inline void add(R int pos, R int val)
{
for (; pos <= hcnt; pos += lowbit(pos)) b[pos] += val;
}
inline ll query(R int pos)
{
R ll ret = ;
for (; pos; pos -= lowbit(pos)) ret += b[pos];
return ret;
}
int main()
{
R int n, m, pcnt = ; scanf("%d%d", &n, &m);
for (R int i = ; i <= n; ++i)
{
R int x, y, pi; scanf("%d%d%d", &x, &y, &pi);
hash[++hcnt] = y;
p[++pcnt] = (Event) {, , x, y, pi};
}
for (R int i = ; i <= m; ++i)
{
R int x_1, y_1, x_2, y_2; scanf("%d%d%d%d", &x_1, &y_1, &x_2, &y_2);
hash[++hcnt] = y_1; hash[++hcnt] = y_2;
p[++pcnt] = (Event) {, i, x_1 - , y_1, y_2};
p[++pcnt] = (Event) {, i, x_2, y_1, y_2};
}
std::sort(hash + , hash + hcnt + );
hcnt = std::unique(hash + , hash + hcnt + ) - hash - ;
std::sort(p + , p + pcnt + );
for (R int i = ; i <= pcnt; ++i)
{
p[i].l = std::lower_bound(hash + , hash + hcnt + , p[i].l) - hash;
if (p[i].type == )
{
add(p[i].l, p[i].r);
}
else
{
p[i].r = std::lower_bound(hash + , hash + hcnt + , p[i].r) - hash;
if (p[i].type == ) ans[p[i].id] -= query(p[i].r) - query(p[i].l - );
else ans[p[i].id] += query(p[i].r) - query(p[i].l - );
}
}
for (R int i = ; i <= m; ++i) printf("%lld\n", ans[i]);
return ;
}
D2T1
4823: [Cqoi2017]老C的方块
刚开始我连构图都没想到。后来看了题解完构图还是构错了。
将格子染成如上图所示的四种颜色,然后每一种方块都可以表示成0-1-2-3的形式。然后构建分层图,一条从s到t的路径表示的就是一个弃疗的方块,所以跑一个最小割即可。然后我一开始好像染色还染错了,注意一下染色的顺序(一定得都是0-1-2-3的形式),如果染不清楚的话可能会有奇怪的错误。还有,10w的网络流到底是怎么跑过去的,我不是很能理解啊。。。
#include <cstdio>
#include <map>
#include <algorithm>
#include <cstring> #define R register
#define P std::pair<int, int>
#define maxn 200010
#define inf 0x7fffffff
#define dmin(_a, _b) ((_a) < (_b) ? (_a) : (_b))
std::map<P, int> id;
int x[maxn], y[maxn], w[maxn];
struct Edge {
Edge *next, *rev;
int to, cap;
} *last[maxn], *cur[maxn], e[maxn * ], *ecnt = e;
inline void link(R int a, R int b, R int w)
{
// printf("%d %d %d\n", a, b, w);
*++ecnt = (Edge) {last[a], ecnt + , b, w}; last[a] = ecnt;
*++ecnt = (Edge) {last[b], ecnt - , a, }; last[b] = ecnt;
}
int dep[maxn], q[maxn], s, t, ans;
inline bool bfs()
{
memset(dep, -, (t + ) << );
dep[q[] = t] = ; R int head = , tail = ;
while (head < tail)
{
R int now = q[++head];
for (R Edge *iter = last[now]; iter; iter = iter -> next)
if (iter -> rev -> cap && dep[iter -> to] == -)
dep[q[++tail] = iter -> to] = dep[now] + ;
}
return dep[s] != -;
}
int dfs(R int x, R int f)
{
if (x == t) return f;
R int used = ;
for (R Edge* &iter = cur[x]; iter; iter = iter -> next)
if (iter -> cap && dep[iter -> to] + == dep[x])
{
R int v = dfs(iter -> to, dmin(f - used, iter -> cap));
iter -> cap -= v;
iter -> rev -> cap += v;
used += v;
if (used == f) return f;
}
return used;
}
void dinic()
{
while (bfs())
{
memcpy(cur, last, sizeof cur);
ans += dfs(s, inf);
}
}
void build(R int _x, R int _y, R int i)
{
R P next;
next = std::make_pair(_x, _y);
if (id[next]) link(id[next] << | , i << , inf);
}
int main()
{
R int c, r, n; scanf("%d%d%d", &c, &r, &n);
for (R int i = ; i <= n; ++i)
{
scanf("%d%d%d", &x[i], &y[i], &w[i]);
R P pos = std::make_pair(x[i], y[i]);
id[pos] = i;
}
s = ; t = n * + ;
for (R int i = ; i <= n; ++i)
{
R int col = y[i] & ? x[i] % : (x[i] % ) ^ ;
// printf("x %d y %d col %d\n", x[i], y[i], col);
link(i << , i << | , w[i]);
if (col == )
{
link(s, i << , inf);
}
else if (col == )
{
build(x[i], y[i] - , i);
build(x[i], y[i] + , i);
build(x[i] + (y[i] & ? - : ), y[i], i);
}
else if (col == )
{
build(x[i] + (y[i] & ? - : ), y[i], i);
}
else if (col == )
{
build(x[i], y[i] - , i);
build(x[i], y[i] + , i);
build(x[i] + (y[i] & ? - : ), y[i], i);
link(i << | , t, inf);
}
}
dinic();
printf("%d\n", ans);
return ;
}
D2T2
4824: [Cqoi2017]老C的键盘
还没做。marked。
Cqoi2017试题泛做的更多相关文章
- 「美团 CodeM 初赛 Round A」试题泛做
最长树链 树形DP.我们发现gcd是多少其实并不重要,只要不是1就好了,此外只要有一个公共的质数就好了.计f[i][j]表示i子树内含有j因子的最长链是多少.因为一个数的不同的质因子个数是log级别的 ...
- Hnoi2017试题泛做
Day1 4825: [Hnoi2017]单旋 注意到二叉查找树的一个性质:其中序遍历就是所有元素按权值排序的顺序. 所以我们可以离线地把这棵树的中序遍历求出来.然后我们在插入的时候就可以用一个set ...
- Shoi2017试题泛做
一口气做完六个省的省选(误) Day1 [Shoi2017]期末考试 枚举最大的天数,然后代价贪心地O(1)计算. #include <cstdio> #include <algor ...
- Sdoi2017试题泛做
Day1 [Sdoi2017]数字表格 推式子的莫比乌斯反演题. #include <cstdio> #include <algorithm> #include <cst ...
- 「美团 CodeM 资格赛」试题泛做
LibreOJ真是吼啊! 数码 推个式子,把枚举因数转为枚举倍数.然后就发现它是根号分段的.然后每一段算一下就好了. #include <cstdio> #include <cstr ...
- codeforces泛做..
前面说点什么.. 为了完成日常积累,傻逼呵呵的我决定来一发codeforces 挑水题 泛做.. 嗯对,就是泛做.. 主要就是把codeforces Div.1的ABCD都尝试一下吧0.0.. 挖坑0 ...
- 学记笔记 $\times$ 巩固 · 期望泛做$Junior$
最近泛做了期望的相关题目,大概\(Luogu\)上提供的比较简单的题都做了吧\(233\) 好吧其实是好几天之前做的了,不过因为太颓废一直没有整理-- \(Task1\) 期望的定义 在概率论和统计学 ...
- 「PKUWC2018/PKUSC2018」试题选做
「PKUWC2018/PKUSC2018」试题选做 最近还没想好报THUSC还是PKUSC,THU发我的三类约(再来一瓶)不知道要不要用,甚至不知道营还办不办,协议还有没有用.所以这些事情就暂时先不管 ...
- 历年NOIP水题泛做
快noip了就乱做一下历年的noip题目咯.. noip2014 飞扬的小鸟 其实这道题并不是很难,但是就有点难搞 听说男神错了一个小时.. 就是$f_{i,j}$表示在第$i$个位置高度为$j$的时 ...
随机推荐
- failed to push some refs to 'git@github.com:cq1415583094/MyBatis.git'解决办法
将本地git仓库代码提交到GitHub上时,出现failed to push some refs to 'git@github.com:cq1415583094/MyBatis.git', 导致的原因 ...
- Luogu P1600[NOIP2016]day1 T2天天爱跑步
号称是noip2016最恶心的题 基本上用了一天来搞明白+给sy讲明白(可能还没讲明白 具体思路是真的不想写了(快吐了 如果要看,参见洛谷P1600 天天爱跑步--题解 虽然这样不好但我真的不想写了 ...
- 洛谷 P2633 Count on a tree 题解
题面 对于每个点建立一颗主席树: 然后按照树上差分的思想统计主席树的前缀和: lca+主席树+前向星存表就可以了: #include <bits/stdc++.h> #define inc ...
- 06: zabbix常见面试题
1.1 zabbix架构 1.zabbix理论 1)Zabbix是一个企业级的.开源的.分布式的监控套件,Zabbix可以监控网络和服务的监控状况. 2)Zabbix利用灵活的告警机制,允许用户对事件 ...
- Transparency Tutorial with C# - Part 3
Download image fade demo - 4 Kb Download image fade source project- 7 Kb Download image fade images ...
- java实现spark常用算子之filter
import org.apache.spark.SparkConf;import org.apache.spark.api.java.JavaRDD;import org.apache.spark.a ...
- 06 基本数据结构 - 双端队列(Deque)
一.双端队列(Deque) - 概念:deque(也称为双端队列)是与队列类似的项的有序集合.它有两个端部,首部和尾部,并且项在集合中保持不变. - 特性:deque 特殊之处在于添加和删除项是非限制 ...
- this(ES6箭头函数里的this)
一,了解前须知 1,箭头函数:出现的作用除了让函数的书写变得很简洁,可读性很好外:最大的优点是解决了this执行环境所造成的一些问题.比如:解决了匿名函数this指向的问题(匿名函数的执行环境具有全局 ...
- 使用HBuilder创建图表
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Firefox 的User Agent 将移除 CPU 架构信息
Mozilla 计划从 Firefox 的 User Agent(用户代理)和几个支持的 API 中移除 CPU 架构信息,以减少 Firefox 用户的“数字指纹”.Web 浏览器会自动向用户在应用 ...