ZOJ Monthly, January 2019
A: Little Sub and Pascal's Triangle
Solved.
题意:
求杨辉三角第n行奇数个数
思路:
薛聚聚说找规律,16说Lucas
答案是 $2^p \;\;p 为 n - 1 中 以2进制表示下1的个数$
证明
$Ans = \sum\limits_0^n C_n^i \;\%\; 2 = \sum\limits_0^n C_{\frac{n}{2}}^{\frac{i}{2}} \cdot C_{n\;\%\;2}^{i\;\%\;2}$
我们考虑 $C_{n \;\%\; 2}^{i \;\%\; 2}$ 一共有四种取值
$C_0^0 \;\; C_0^1\;\; C_1^0 \;\; C_1^1$
我们发现 只有 $C_0^1的值为0 其他三个值都为1$
那么我们再考虑$C_n^i 这个式子$
它通过卢卡斯定理分解 实际上可以写成
我们先假设
$i 以二进制表示为$
$a_1, a_2, \cdots a_k$
$n 以二进制表示为$
$b_1, b_2, \cdots b_k$
那么 $C_n^i = C_{b_1}^{a_1} \cdot C_{b_2}^{a_2} \cdots C_{b_k}^{a_k}$
那么我们发现,
要满足$C_n^i\;\%\; 2 = 1 \;\;$
$那么在b_y = 1的位置上,i在对应位置上取0或者1都可以$
在$b_y = 0 的位置上,i在对应位置的取值已经固定 是 0$
那么$i的取值一共有2^p p 为(n - 1)以2进制表示下1的个数$
为什么是$n - 1 \;\;因为杨辉三角是从第0行开始的$
#include<bits/stdc++.h> using namespace std; typedef long long ll; ll n; int main()
{
int t;
scanf("%d", &t);
while(t--)
{
scanf("%lld", &n);
n--;
ll tmp = ;
while(n)
{
if(n & ) tmp++;
n >>= ;
}
ll ans = 1ll << tmp;
printf("%lld\n", ans);
}
return ;
}
B:Little Sub and his Geometry Problem
Solved.
题意:
一个点的权值定义为它到左下角所有点的曼哈顿距离
q次查询, 每次查询权值为c的点的个数
思路:
$给出的点沿着x轴正方向, y轴正方向都是严格单调递增的。$
$因此可以枚举x轴, 动态维护左下角点个数以及权值, 向右走的同时$
$将横坐标相同, 纵坐标<=当前位置的点假如, 向下走的时候将纵坐标相同给的点移除$
$当前权值为c时 ans++$
(薛聚聚:不会写题解啊)
#include<bits/stdc++.h> using namespace std; typedef long long ll;
typedef unsigned long long ull; const double eps = 1e-;
const ll MOD = 1e9 + ;
const ll INFLL = 0x3f3f3f3f3f3f3f3f;
const int INF = 0x3f3f3f3f;
const int maxn = 1e5 + ; int n, k;
ll sum, cnt;
ll sum_arr[maxn], cnt_arr[maxn];
ll ans[]; struct node {
int x, y;
node() {}
node(int x, int y) :x(x), y(y) {}
bool operator < (const node &other) const
{
return x == other.x ? y < other.y : x < other.x;
}
}P[maxn]; ll solve(ll c)
{
cnt = sum = ;
memset(sum_arr, , sizeof sum_arr);
memset(cnt_arr, , sizeof cnt_arr);
int index = ;
int ans = ;
int y = n;
for (int x = ; x <= n; ++x)
{
while (index <= k && P[index].x <= x)
{
if (P[index].y <= y)
{
cnt++;
sum += P[index].x + P[index].y;
sum_arr[P[index].y] += P[index].x + P[index].y;
cnt_arr[P[index].y]++;
}
++index;
}
while ((x + y) * cnt - sum > c)
{
sum -= sum_arr[y];
cnt -= cnt_arr[y];
--y;
}
if ((x + y) * cnt - sum == c) ++ans;
}
return ans;
} void RUN()
{
int t;
scanf("%d", &t);
while (t--)
{
scanf("%d %d", &n, &k);
for (int i = ; i <= k; ++i) scanf("%d %d", &P[i].x, &P[i].y);
sort(P + , P + + k);
int q;
scanf("%d", &q);
for (int i = ; i <= q; ++i)
{
ll c;
scanf("%lld\n", &c);
ans[i] = solve(c);
}
for (int i = ; i <= q; ++i) printf("%lld%c", ans[i], " \n"[i == q]);
}
} int main()
{
#ifdef LOCAL_JUDGE
freopen("Text.txt", "r", stdin);
#endif // LOCAL_JUDGE RUN(); #ifdef LOCAL_JUDGE
fclose(stdin);
#endif // LOCAL_JUDGE
return ;
}
E:Little Sub and Mr.Potato's Math Problem
Solved.
题意:
给出n, k
将n个数按照字典序排序, k所在的位置为m
现在给出k, m 求最小的n
思路:
当k为10的整数倍, 那么它一定在第$log_{10^k}$
$随后统计当n=k的时候, 排在k前面的个数,和m比较, 判断是否合法$
$接着不断增加n, 统计每次增长排在k前面的个数, 随后输出n$
(薛聚聚:不会写题解啊)
#include<bits/stdc++.h> using namespace std; typedef long long ll;
typedef unsigned long long ull; const double eps = 1e-;
const ll MOD = 1e9 + ;
const ll INFLL = 0x3f3f3f3f3f3f3f3f;
const int INF = 0x3f3f3f3f;
const int maxn = 1e5 + ; ll k, m;
int arr[maxn];
ll pow_10[]; void Init()
{
pow_10[] = ;
for (int i = ; i <= ; ++i)
{
pow_10[i] = pow_10[i - ] * ;
}
} void solve()
{
ll num = ;
for (int i = ;; ++i)
{
if (num > k) break;
else if (num == k)
{
if (i == m)
{
printf("%lld\n", k);
return;
}
else
{
puts("");
return;
}
}
num *= ;
}
int len = ;
num = k;
while (num)
{
arr[++len] = num % ;
num /= ;
}
reverse(arr + , arr + + len);
ll ans = ;
num = ;
for (int i = ; i <= len; ++i)
{
num = num * + arr[i];
ans += num - pow_10[i - ];
if (i != len) ++ans;
}
if (ans >= m)
{
puts("");
return;
}
else if (ans == m - )
{
printf("%lld\n", k);
return;
}
while ()
{
len++;
num *= ;
if (ans + num - pow_10[len - ] >= m - )
{
ans = pow_10[len - ] + m - ans - ;
printf("%lld\n", ans);
return;
}
ans += num - pow_10[len - ];
}
} void RUN()
{
Init();
int t;
scanf("%d", &t);
while (t--)
{
scanf("%lld %lld", &k, &m);
solve();
}
} int main()
{
#ifdef LOCAL_JUDGE
freopen("Text.txt", "r", stdin);
#endif // LOCAL_JUDGE RUN(); #ifdef LOCAL_JUDGE
fclose(stdin);
#endif // LOCAL_JUDGE
return ;
}
F:Little Sub and a Game
Unsolved.
题意:
有两个玩家$A, B 刚开始有一个变量v = 0$
$A玩家有N个pair, B玩家有M个pair \;\; pair 为(x, y) A玩家N次操作,每次选择x_i 或者 y_i 来异或v B玩家有M次操作$
$A玩家先进行N次操作, B玩家再进行M次操作$
A玩家想让$v尽量大,B玩家想让v尽量小$
两个玩家都采用最优策略,求最后$v$的值
G:Little Sub and Tree
Solved.
题意:
给出一个无根树,选取$k个点对所有点进行编码$
按如下方式进行编码
$令选取的k个点为 s_1, s_2 \cdots s_k$
编出的码有$k位$
$对于u来说,第i位的编码为 s_i -> u的简单路径上的点的总数$
思路:
如果是一条链的话 那么取两端的一个就可以了
那么我们考虑一棵树中,如果某个节点的儿子对应的子树是一条链
那么这条链是可以被缩点成一个叶节点 而对答案没有影响
那么现在树就被我们简化成了 只有叶节点的子树
首先注意到,一棵子树内节点的区分和这棵子树外的点的选取是没有关系的
那么我们考虑 一个点对应的儿子当中,如果有$x个叶节点$
那么这x个节点要想被区分,就需要取$x - 1$ 个
再考虑一个点的儿子对应的子树,如果子树内都被区分了,那么合并起来也是被区分的
那么考虑选谁作为根
只要根不在链上就可以了,因为如果在链上会对缩点产生影响
#include <bits/stdc++.h>
using namespace std; #define N 100010
int t, n, root, d[N], fa[N];
vector <int> G1[N], G2[N], res; int pre(int u)
{
int id = -;
int cnt = G1[u].size() - ;
if (cnt == ) return u;
for (auto v : G1[u]) if (v != fa[u])
{
fa[v] = u;
id = pre(v);
G2[u].push_back(id);
}
if (cnt == && u != root) return id;
else return u;
} void DFS(int u)
{
int need = ;
for (auto v : G2[u]) if (v != fa[u] && !d[v])
++need;
--need;
for (auto v : G2[u]) if (v != fa[u])
{
fa[v] = u;
if (!d[v] && need > )
{
--need;
res.push_back(v);
}
DFS(v);
}
} int main()
{
scanf("%d", &t);
while (t--)
{
scanf("%d", &n);
for (int i = ; i <= n; ++i)
{
G1[i].clear();
G2[i].clear();
d[i] = -;
fa[i] = ;
}
res.clear();
root = -; for (int i = , u, v; i < n; ++i)
{
scanf("%d%d", &u, &v);
G1[u].push_back(v);
G1[v].push_back(u);
++d[u]; ++d[v];
}
if (n == )
{
puts("1\n1");
continue;
}
for (int i = ; i <= n; ++i) if (d[i] > )
{
root = i;
break;
}
if(root == -)
{
int ans = ;
for(int i = ; i <= n; ++i) if(d[i] == ) ans = i;
printf("1\n%d\n", ans);
continue;
}
pre(root);
DFS(root);
//puts("bug");
//for (int i = 1; i <= n; ++i) printf("%d %d\n", i, fa[i]);
//puts("bug");
int k = res.size();
printf("%d\n", k);
for (int i = ; i < k; ++i) printf("%d%c", res[i], " \n"[i == k - ]);
}
return ;
}
I:Little Sub and Isomorphism Sequences
Solved.
题意:
有一个$A[], 两种操作$
- $A_x -> y$
- 查询最长同构子串
思路:
考虑最长同构子串肯定会有重叠部分,那么两端出去的部分就是不同的部分
那么这个不同的部分让它长度为1即可,因为多余的长度是没有用的
那么题意就可以转化为 找一个最长的子串,使得两端相同即可
将数据离散化 开2e5个set维护每个数的位置
然后用数据结构 维护答案的最大值 即可
#include <bits/stdc++.h>
using namespace std; #define N 200010
int t, n, m, a[N], b[N];
struct qnode
{
int op, x, y;
void scan()
{
scanf("%d", &op);
if (op == )
{
scanf("%d%d", &x, &y);
b[++b[]] = y;
}
}
}q[N];
set <int> s[N];
namespace SEG
{
int a[N << ];
void build(int id, int l, int r)
{
a[id] = -;
if (l == r) return;
int mid = (l + r) >> ;
build(id << , l, mid);
build(id << | , mid + , r);
}
void update(int id, int l, int r, int pos, int v)
{
if (l == r)
{
a[id] = v;
return;
}
int mid = (l + r) >> ;
if (pos <= mid) update(id << , l, mid, pos, v);
else update(id << | , mid + , r, pos, v);
a[id] = max(a[id << ], a[id << | ]);
}
}
void Hash()
{
sort(b + , b + + b[]);
b[] = unique(b + , b + + b[]) - b - ;
for (int i = ; i <= n; ++i) a[i] = lower_bound(b + , b + + b[], a[i]) - b;
for (int i = ; i <= m; ++i) if (q[i].op == ) q[i].y = lower_bound(b + , b + + b[], q[i].y) - b;
} int main()
{
scanf("%d", &t);
while (t--)
{
scanf("%d%d", &n, &m);
SEG::build(, , n + m);
for (int i = ; i <= n + m; ++i) s[i].clear(); b[] = ;
for (int i = ; i <= n; ++i) scanf("%d", a + i), b[++b[]] = a[i];
for (int i = ; i <= m; ++i) q[i].scan(); Hash();
for (int i = ; i <= n; ++i) s[a[i]].insert(i);
for (int i = ; i <= n + m; ++i) if (s[i].size() >= )
SEG::update(, , n + m, i, *s[i].rbegin() - *s[i].begin());
for (int i = ; i <= m; ++i)
{
if (q[i].op == )
{
int v = a[q[i].x], x = q[i].x, y = q[i].y;
s[v].erase(x);
SEG::update(, , n + m, v, s[v].size() >= ? *s[v].rbegin() - *s[v].begin() : -);
a[q[i].x] = y;
v = y;
s[v].insert(x);
SEG::update(, , n + m, v, s[v].size() >= ? *s[v].rbegin() - *s[v].begin() : -);
}
else printf("%d\n", SEG::a[]);
}
}
return ;
}
ZOJ Monthly, January 2019的更多相关文章
- ZOJ Monthly, January 2019 Little Sub and his Geometry Problem 【推导 + 双指针】
传送门:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5861 Little Sub and his Geometry Prob ...
- ZOJ Monthly, January 2019 Little Sub and Isomorphism Sequences 【离线离散化 + set + multiset】
传送门:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5868 Little Sub and Isomorphism Seque ...
- ZOJ Monthly, January 2019 Little Sub and his Geometry Problem ZOJ4082(模拟 乱搞)
在一次被自己秀死... 飞机 题目: 给出N,K, Q; 给出一个N*N的矩阵 , 与K个特殊点 , 与Q次查询 , 每次查询给出一个C , 问 在这个N*N矩阵中 , 有多少的点是满足这样的一个关 ...
- ZOJ Monthly, January 2019 I Little Sub and Isomorphism Sequences(set 妙用) ZOJ4089
写这篇博客来证明自己的愚蠢 ...Orz 飞机 题意:给定你个数组,以及一些单点修改,以及询问,每次询问需要求得,最长的字串长度,它在其他位置存在同构 题解:经过一些奇思妙想后 ,你可以发现问题是传 ...
- ZOJ Monthly, January 2018 训练部分解题报告
A是水题,此处略去题解 B - PreSuffix ZOJ - 3995 (fail树+LCA) 给定多个字符串,每次询问查询两个字符串的一个后缀,该后缀必须是所有字符串中某个字符串的前缀,问该后缀最 ...
- matrix_2015_1 138 - ZOJ Monthly, January 2015
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3844 第一个,n个数,每次操作最大数和最小数都变成他们的差值,最后n个数相 ...
- ZOJ Monthly, January 2018
A 易知最优的方法是一次只拿一颗,石头数谁多谁赢,一样多后手赢 #include <map> #include <set> #include <ctime> #in ...
- ZOJ Monthly, January 2018 Solution
A - Candy Game 水. #include <bits/stdc++.h> using namespace std; #define N 1010 int t, n; int a ...
- ZOJ Monthly, January 2019-Little Sub and Pascal's Triangle
这个题的话,它每行奇数的个数等于该行行号,如果是0开始的,就该数的二进制中的1的个数,设为k,以它作为次数,2k就是了. #include <stdio.h> int main() { i ...
随机推荐
- HttpServletResponse status对应的状态信息
1xx - 信息提示 这些状态代码表示临时的响应.客户端在收到常规响应之前,应准备接收一个或多个 1xx 响应. ·0 - 本地响应成功. · 100 - Continue 初始的请求已 ...
- 苹果降频门:旧款iPhone哪些功能受到影响
要说苹果最近发生的大事,就数网络上传的沸沸扬扬的降频门事件了,近期苹果在新发布的iOS 11系统中新增了一项功能,意在降低旧款手机的电量消耗,但限制了旧款iPhone的性能,那么iPhone有哪些功能 ...
- php第二例
参考: http://www.php.cn/code/3645.html 前言 由于navicat在linux平台不能很好的支持, PHP的学习转到windows平台. php IDE: PhpSto ...
- 十分钟理解Java中的动态代理
十分钟理解 Java 中的动态代理 一.概述 1. 什么是代理 我们大家都知道微商代理,简单地说就是代替厂家卖商品,厂家“委托”代理为其销售商品.关于微商代理,首先我们从他们那里买东西时通常不知道 ...
- ASP.NET 4.0尚未在Web服务器注册 解决
http://www.cnblogs.com/lvxiouzi/p/3511446.html 安装asp.net 4.0.30319.0版本 命令: %windir%\Microsoft.NET\Fr ...
- JS对象添加新的字段
var test={name:"name",age:"12"}; test.id = "12345"; 直接定义添加就成了
- 策略模式原理及Java代码实例
一.策略模式的定义 —— 定义了一组算法,将每个算法包装起来,并且使它们之间可以互换 —— 策略模式使这些算法在客户端调用它们的时候能够相互不影响的变化,改变不同算法的实现方式不影响客户端的使用,即策 ...
- Java初学者笔记五:泛型处理
一.泛型类: 泛型是指适用于某一种数据类型而不是一个数据机构中能存不同类型 import java.io.*; import java.nio.file.Files; import java.nio. ...
- python 进行抓包嗅探
一.绪论 最近一直想弄一个代理,并且对数据包进行解读,从而完成来往流量的嗅探.于是今天学习了一下如何使用Python抓包并进行解包. 首先要用到两个模块 dpkt(我这边ubuntu16.04 LTS ...
- mysql 效率 inner join 与 where in
-- report 123.77k行 report_loss 620 行 -- inner join ;report_loss 索引 all report 索引 eq_ref ; -- total 0 ...