Educational Codeforces Round 33 (Rated for Div. 2) 题解
A.每个状态只有一种后续转移,判断每次转移是否都合法即可。
#include <iostream>
#include <cstdio>
using namespace std;
int a[], n;
bool check(int x){
if(a[] == x) return false;
int l = a[], r = x, s = -a[]-x;
for(int i = ; i <= n; i++){
if(a[i] == s) return false;
l = a[i]; r = s; s = -l-r;
}
return true;
} int main()
{
cin>>n;
for(int i = ; i <= n; i++) cin>>a[i];
int f = ;
if(check()) f = ;
if(f == ) printf("YES");
else printf("NO");
return ;
}
B.按照题意枚举约数判断即可。
#include <iostream>
using namespace std;
int n;
bool check(int x){
for(int i = ; i <= ; i++){
if( ((<<i) - )*(<<(i-)) == x) return true;
if( ((<<i) - )*(<<(i-)) > x) return false;
}
}
int a[];
int main()
{
int ans = , temp = , last = , L;
cin>>n;
for(int i = ; i <= n; i++){
if(n%i == )
if(check(i))
ans = max(ans, i);
}
cout<<ans<<endl;
}
C.先用并查集并起来,然后瞎搞即可。
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn = 1e5 + ;
int a[maxn], f[maxn], v[maxn], s[maxn], M[maxn], x, y;
int find(int x) { return x == f[x] ? f[x] : f[x] = find(f[x]); }
int main()
{
long long ans = ;
int n, m;
cin>>n>>m;
for(int i = ; i <= n; i++){
scanf("%d", &a[i]);
f[i] = i;
v[i] = a[i];
}
for(int i = ; i <= m; i++){
scanf("%d %d", &x, &y);
f[find(x)] = find(y);
}
for(int i = ; i <= n; i++){
v[find(i)] = min(v[find(i)], v[i]);
}
for(int i = ; i <= n; i++){
if(M[find(i)] == ){
M[find(i)] = ;
ans += (long long)v[find(i)];
}
}
cout<<ans<<endl;
}
D.一道题意非常困难的题目orz。
题意大概就是:给你每天的金钱变化,你可以选择加任意数量的钱,但是需要保证每个时刻的钱数不超过d,而且当金钱变化为0时,此时钱的数量必须非负(check一次)
最后还是读错题了。
这道题贪心是对的,先考虑画出价格的折线图。
在第i天加钱,就相当于抬高i天以后的折线。
贪心地想,反正加更多的钱总是更优
所以如果在第i天加钱,就尽量多的加钱
而能加的钱数就是上限d - Max[i](Max为从i到n的后缀),如果比这个还多,那么后面必定会超
所以就在每个需要加钱的位置都贪心地加钱即可。
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn = 1e5 + ;
int a[maxn], n;
long long b[maxn], Max[maxn], d;
int main()
{
cin>>n>>d;
for(int i = ; i <= n; i++) scanf("%d", &a[i]);
b[] = ;
for(int i = ; i <= n; i++) b[i] = b[i-] + a[i];
Max[n] = b[n];
for(int i = n-; i >= ; i--) Max[i] = max(b[i], Max[i+]);
int t = , f = ;
if(Max[] > d){
f = ;
} else {
long long h = ;
for(int i = ; i <= n; i++){
if(a[i] == && b[i] + h < ){
h = d - Max[i];
t++;
if(b[i] + h < ) { f = ; break; }
}
}
}
if(f){
printf("-1");
} else printf("%d", t);
return ;
}
E.给你一个数x,你需要把它拆成y个数的乘积,只要对应位置的yi有一个不同,方案就是不同的,问有多少种方案(负数也算)
首先考虑只有正数。
把x质因数拆分,然后对于每个质因数
你需要把它分配个y个数,比如24 = 3*2^3
其中就需要把3个2分配给y个数,实际上就是y个不同的盒子,3个球,问有多少种方案
答案就是C(y+3-1, y-1)
然后每个质因数乘起来就可以了。
如果是负数,那么其实就是每个正数的方案选出2个变成负数
就是C(n, 0) + C(n, 2) + .... = 2^(n-1)
最后都乘起来就可以了。
这题很蠢的是数组越界了,因为n+m大于1e6,但是没有预处理到(以及找质因数的写法一定要注意)
#include <iostream>
#include <vector>
#include <cstdio>
#define mp make_pair
#define fi first
#define se second
using namespace std;
vector< pair<int, int> > V;
const int MOD = 1e9 + ;
typedef long long LL;
LL f[], invf[];
LL mypow(LL a, LL b){
LL ans = ; for(; b; b >>= , (a *= a) %= MOD) if(b&) (ans *= a) %= MOD; return ans;
}
LL C(LL n, LL m){
return f[n]*invf[m]%MOD*invf[n-m]%MOD;
}
int T, x, y;
int main()
{
cin>>T;
f[] = ;
for(int i = ; i <= ; i++) f[i] = f[i-]*i%MOD;
invf[] = mypow(f[], MOD-);
for(int i = -; i >= ; i--) invf[i] = (invf[i+]*(i+))%MOD;
while(T--){
scanf("%d %d", &x, &y);
int t = x;
long long ans = ;
for(int i = ; i*i <= x; i++){
if(t % i == ){
int temp = ;
while(t % i == ) temp++, t /= i;
(ans *= C(temp+y-, y-) ) %= MOD;
}
}
if(t != ) (ans *= y) %= MOD;
(ans *= mypow(, y-)) %= MOD;
printf("%I64d\n", ans);
}
return ;
}
F.给定一棵树,每次询问x构成的子树内,距离x结点小于等于k的点中值最小的是多少。强制在线
这题我是用可持久化线段树+维护dfs序做的,复杂度是nlogn。不过也有很暴力的线段树维护dfs序nlognlogn做法
具体思想就是可持久化线段树的结点对应是dfs序
插入的时间是按深度排序。
那么询问x,k
就是问插入时间从1~deep[x]+k所构成的树中,x的子树中结点最小的值是多少。
然后维护dfs序,就是查询tree(deep[x] + k, ein[x], eout[x])这个区间的值。
大概就是这样,没什么很坑的地方。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
const int maxn = 2e5 + ;
struct Node{
Node *l, *r;
int v;
void maintain(){
v = min(l->v, r->v);
}
}pool[maxn*], *root[maxn], *null;
int pooltot = ;
Node *newnode(){
Node* temp = &pool[pooltot++];
temp->l = temp->r = null; temp->v = 1e9; //
return temp;
}
void init(){
null = new Node();
null->l = null->r = null;
null->v = 1e9; //
}
void Insert(Node *&o, Node *o2, int l, int r, int k, int v){
if(o == null) o = newnode();
if(l == r) { o->v = min(v, o2->v); return; } //
int mid = (l+r)/;
if(k <= mid) {
Insert(o->l, o2->l, l, mid, k, v);
o->r = o2->r;
} else {
Insert(o->r, o2->r, mid+, r, k, v);
o->l = o2->l;
}
o->maintain();
}
int Query(Node *o, int l, int r, int L, int R){
if(o == null) return 1e9; //
if(L <= l && r <= R) return o->v;
int mid = (l+r)/, ans = 1e9; //
if(L <= mid) ans = min(ans, Query(o->l, l, mid, L, R)); //
if(R > mid) ans = min(ans, Query(o->r, mid+, r, L, R)); //
return ans;
}
int tot = , Maxd, timer = ;
int ein[maxn], deep[maxn], eout[maxn], a[maxn], lastd[maxn];
vector<int> D[maxn], G[maxn];
void dfs(int x, int fa, int d){
ein[x] = ++tot;
deep[x] = d;
Maxd = max(d, Maxd);
D[d].push_back(x);
for(auto to : G[x]){
if(to == fa) continue;
dfs(to, x, d+);
}
eout[x] = tot;
}
int n, r, x, y, q;
int main(){
init();
cin>>n>>r;
for(int i = ; i <= n; i++) scanf("%d", &a[i]);
for(int i = ; i < n; i++){
scanf("%d %d", &x, &y);
G[x].push_back(y);
G[y].push_back(x);
}
dfs(r, r, );
for(int i = ; i <= n + ; i++) root[i] = newnode();
for(int i = ; i <= Maxd; i++){
for(auto x : D[i]){
Insert(root[timer+], root[timer], , tot, ein[x], a[x]);
timer++;
}
lastd[i] = timer;
}
scanf("%d", &q);
int last = ;
while(q--){
scanf("%d %d", &x, &y);
x = (x+last)%n + ;
y = (y+last)%n;
printf("%d\n", last = Query(root[lastd[min(Maxd, deep[x]+y)]], , tot, ein[x], eout[x]));
}
}
Educational Codeforces Round 33 (Rated for Div. 2) 题解的更多相关文章
- Educational Codeforces Round 63 (Rated for Div. 2) 题解
Educational Codeforces Round 63 (Rated for Div. 2)题解 题目链接 A. Reverse a Substring 给出一个字符串,现在可以对这个字符串进 ...
- Educational Codeforces Round 65 (Rated for Div. 2)题解
Educational Codeforces Round 65 (Rated for Div. 2)题解 题目链接 A. Telephone Number 水题,代码如下: Code #include ...
- Educational Codeforces Round 64 (Rated for Div. 2)题解
Educational Codeforces Round 64 (Rated for Div. 2)题解 题目链接 A. Inscribed Figures 水题,但是坑了很多人.需要注意以下就是正方 ...
- Educational Codeforces Round 60 (Rated for Div. 2) 题解
Educational Codeforces Round 60 (Rated for Div. 2) 题目链接:https://codeforces.com/contest/1117 A. Best ...
- Educational Codeforces Round 58 (Rated for Div. 2) 题解
Educational Codeforces Round 58 (Rated for Div. 2) 题目总链接:https://codeforces.com/contest/1101 A. Min ...
- Educational Codeforces Round 33 (Rated for Div. 2) E. Counting Arrays
题目链接 题意:给你两个数x,yx,yx,y,让你构造一些长为yyy的数列,让这个数列的累乘为xxx,输出方案数. 思路:考虑对xxx进行质因数分解,设某个质因子PiP_iPi的的幂为kkk,则这个 ...
- Educational Codeforces Round 33 (Rated for Div. 2) F. Subtree Minimum Query(主席树合并)
题意 给定一棵 \(n\) 个点的带点权树,以 \(1\) 为根, \(m\) 次询问,每次询问给出两个值 \(p, k\) ,求以下值: \(p\) 的子树中距离 \(p \le k\) 的所有点权 ...
- Educational Codeforces Round 33 (Rated for Div. 2)A-F
总的来说这套题还是很不错的,让我对主席树有了更深的了解 A:水题,模拟即可 #include<bits/stdc++.h> #define fi first #define se seco ...
- Educational Codeforces Round 33 (Rated for Div. 2) D. Credit Card
D. Credit Card time limit per test 2 seconds memory limit per test 256 megabytes input standard inpu ...
随机推荐
- 【LG5021】[NOIP2018]赛道修建
[LG5021][NOIP2018]赛道修建 题面 洛谷 题解 NOIP之前做过增强版还没做出来\(QAQ\) 一看到题目中的最大值最小,就很容易想到二分答案 重点是考虑如何\(check\) 设\( ...
- 1109: [POI2007]堆积木Klo
1109: [POI2007]堆积木Klo https://lydsy.com/JudgeOnline/problem.php?id=1109 分析: 首先是dp,f[i]表示到第i个的最优值,f[i ...
- Swing 解决 idea 找不到创建gui form的问题
果然,寄希望于百度google不如自己动手,还是得吃透文档, 然后就是对于别人的博客要严格对照步骤来,否则都容易达不到效果 这边gui form在idea下找不到创建,百度google一个说的也没有, ...
- Struts 2(二):使用Struts2
本文简单描述如何在Eclipse中使用使用Struts2,并介绍一下Struts2的配置文件 注:Struts2默认需要Java 5.0及其以上版本的运行环境支持,Web容器需要支持Servlet 2 ...
- 我们一起学习WCF 第十篇Wcf中实现事务
数据一致性在工作中显得非常重要,有时候我们库中出现脏数据导致程序报错,但是又很难发现这样的错误,所以为了数据的完整性建议在程序中加入事物. 什么是事物:我们都有团队合作吧,比喻团队有3个人,a负责设计 ...
- Linux 安装Redis<准备>(使用Mac远程访问)
阅读本文需要一定的Linux基础 一 Redis简介 redis是用c语言编写的一款开源的高性能键值对(key-value)数据库 它通过提供多种键值数据类型来适应不同场景下的存储需求 二 Redis ...
- VR电竞游戏在英特尔®架构上的用户体验优化
作为人与虚拟世界之间的新型交互方式,VR 能够让用户在模拟现实中获得身临其境的感受.但是,鉴于 VR 的帧预算为每帧 11.1ms (90fps),实现实时渲染并不容易,需要对整个场景渲染两次(一只眼 ...
- KRKR基础篇(二)
这里介绍一些krkr的语法规范,具体的命令含义及用法以后再叙述 一:kag语法及基本概念 KAG使用的剧本语言为KAG Script,文件扩展名为.ks 脚本内的文字除 注释, 命令 , 段落标 ...
- Mysql基础操作语句
SQL 简单的增删改查 不区分大小写, 表名和字段名可不加引号 查询语句 SELECT * FROM `table_name`; -- 注释 CTRL+/ : 注释 CTRL+/ : 取消注释 /* ...
- cinder创建volume的流程-简单梳理
1. cinder-api接收到创建的请求,入口:cinder.api.v2.volumes.VolumeController#create,该方法主要负责一些参数的重新封装和校验,然后调用cinde ...