A - Alice’s Print Service
题目链接 https://vjudge.net/contest/228708#problem/A
题解
签到题
二分
有个小坑点,要维护一个最小值的数组
#include<set>
#include<map>
#include<cmath>
#include<stack>
#include<queue>
#include<vector>
#include<string>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define fi first
#define se second
#define fio ios::sync_with_stdio(false);cin.tie(0)
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> Pii;
const int INF = 0x3f3f3f3f;
const int M = 100005;
const int MOD = 1e9 + 7;
const double pi = acos(-1);
struct P
{
int l, v;
ll vv;
bool operator < (const P& a) const
{
return l < a.l;
}
}p[100005];
ll mm[100005];
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
int n, m;
scanf("%d %d", &n, &m);
for(int i = 0; i < n; ++i)
{
scanf("%d %d", &p[i].l, &p[i].v);
p[i].vv = p[i].l * 1ll * p[i].v;
}
ll mi = p[n - 1].vv;
for(int i = n - 1; i >= 0; --i)
{
if(mi > p[i].vv) mi = p[i].vv;
mm[i] = mi;
}
for(int i = 0; i < m; ++i)
{
int x;
ll ans = 0;
scanf("%d", &x);
if(x == 0)
{
puts("0");
continue;
}
int t = upper_bound(p, p + n, P{x, 0, 0}) - p;
if(t == n) ans = p[t - 1].v * 1ll * x;
else ans = min(mm[t], p[t - 1].v * 1ll * x);
printf("%lld\n", ans);
}
}
return 0;
}
B - Bob’s new toy
题目链接 https://vjudge.net/contest/228708#problem/B
C - Collision
题目链接 https://vjudge.net/contest/228708#problem/C
D - Arnold
题目链接 https://vjudge.net/contest/228708#problem/D
题解
对于fib数列的最小循环节的求法,我们可以这样:
1、令n=p1^m1 * p2^m2 * p3^m3……
2、分别计算fib数列在模p1^m1,p2^m2……意义下的最小循环节
我们考虑如何计算p1^m1的循环节
这里有一个定理:G(p1^m1)=G(p1)*p1^(m-1)
我们只需要计算G(p)就可以了
f(n) = a * f(n - 1) + b * f(n - 2);
f(1) = c, f(2) = d // 可忽略
求f(n)mod p循环节长度
c = a * a + 4b
是模p的二次剩余时,枚举n = p - 1的因子
否则 枚举n=2*(p+1)的因子
3、模n意义下的最小循环节为2步骤各循环节的LCM
代码
//#pragma comment(linker, "/stack:200000000")
//#pragma GCC optimize("Ofast,no-stack-protector")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//#pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#define fi first
#define se second
#define lson l,mid,o<<1
#define rson mid+1,r,o<<1|1
#define fio ios::sync_with_stdio(false);cin.tie(0)
using namespace std;
typedef long long LL;
typedef unsigned long long uLL;
typedef pair<int, int> P;
typedef pair<P, int> PII;
typedef pair<LL, int> PIII;
const LL INF = 0x3f3f3f3f;
const int N = 1e6 + 10;
const int M = 3e6 + 10;
//const LL mod = 1e9 + 7;
const double PI=acos(-1);
inline LL ab(LL x){return x < 0 ? -x : x;}
inline LL mm(LL x, LL p){return x >= p ? x - p : x < 0 ? x + p : x;}
LL mod;
LL mul(LL x,LL y){
LL res = 0;
while(y){
if(y & 1) res = mm(res + x, mod);
x = mm(x << 1, mod);
y >>= 1;
}
return res;
}
LL gcd(LL x, LL y){
return x ? gcd(y % x, x) : y;
}
LL lcm(LL x, LL y){
return x / gcd(x, y) * y;
}
LL qpow(LL x, LL y){
LL res = 1ll;
x %= mod;
while(y){
if(y & 1) res = mul(res , x);
x = mul(x , x);
y >>= 1;
}
return res;
}
/// 判断x是否是p的二次剩余;
bool legendre(LL x, LL p) {
LL t = qpow(x, (p - 1) >> 1);
if(t == 1ll) return true;
return false;
}
struct Matrix{
LL v[2][2];
Matrix operator * (Matrix &it) const{
Matrix res;
memset(res.v, 0, sizeof res.v);
for(int i = 0; i < 2; ++i)
for(int j = 0; j < 2; ++j)
for(int h = 0; h < 2; ++h)
res.v[i][j] = mm(res.v[i][j] + mul(v[i][h] , it.v[h][j]), mod);
return res;
}
}init_mat, mat;
Matrix qpow(Matrix now, LL y){
Matrix res;
res = init_mat;
while(y){
if(y & 1) res = res * now;
now = now * now;
y >>= 1;
}
return res;
}
LL st[N], tot;
bool ok(Matrix &now){
return ((now.v[0][0] + now.v[0][1]) % mod == 1ll && (now.v[1][0] + now.v[1][1]) % mod == 0ll);
}
LL get_loop(LL c, LL p){
if(p==2)return 3;
else if(p==3)return 8;
else if(p==5)return 20;
mod = p;
if(legendre(c, p)) p = mod - 1;
else p = 2ll * (mod + 1);
tot = 0;
Matrix now;
for(LL i = 1; i * i <= p; ++i){
if(p % i == 0){
now = qpow(mat, i-1);
if(ok(now)) return i;
if(i != p / i) st[++tot] = p / i;
}
}
while(tot){
now = qpow(mat, st[tot]-1);
if(ok(now)) return st[tot];
tot--;
}
return 0;
}
LL solve(LL c, LL n){
LL ans = 1, now;
for(LL i = 2; i * i <= n; ++i){
if(n % i == 0){
now = 1;
while(n % i == 0) now *= i, n /= i;
now /= i;
now *= get_loop(c, i);
ans = lcm(ans, now);
}
}
if(n != 1){
now = get_loop(c, n);
ans = lcm(ans, now);
}
return ans;
}
int main()
{
init_mat.v[0][0] = init_mat.v[1][1] = 1;
mat.v[0][0] = 1, mat.v[0][1] = 1;
mat.v[1][0] = 1, mat.v[1][1] = 0;
LL n;
while(~scanf("%lld", &n)){
LL ans = solve(5ll, n);
if(!(ans & 1)) ans >>= 1;
printf("%lld\n", ans);
}
return 0;
}
/*
4461651651
231651213
216512121
1115132185
1165121213
216511562
216513213
1654234161
2165121651
156121561
165485165
21651
2621
15613
1365416
*/
E - Easy Problem Once More
题目链接 https://vjudge.net/contest/228708#problem/E
F - Winter’s Coming
题目链接 https://vjudge.net/contest/228708#problem/F
G - Graph Reconstruction
题目链接 https://vjudge.net/contest/228708#problem/G
题解
贪心的从度数最大的点开始建边,每次和剩下来的前k大建,然后就一直贪心下去就可以了.
多解的话考虑将存在两条边uv和u’v’, 那么把他换成uv’和u’v就可以了
代码
//#pragma comment(linker, "/stack:200000000")
//#pragma GCC optimize("Ofast,no-stack-protector")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//#pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#define fi first
#define se second
#define lson l,mid,o<<1
#define rson mid+1,r,o<<1|1
#define fio ios::sync_with_stdio(false);cin.tie(0)
using namespace std;
typedef long long LL;
typedef unsigned long long uLL;
typedef pair<int, int> P;
typedef pair<P, LL> PII;
typedef pair<LL, int> PIII;
const LL INF = 0x3f3f3f3f;
const int N = 2e5 + 10;
const int M = 3e6 + 10;
const LL mod = 1e9 + 7;
const double PI=acos(-1);
inline LL ab(LL x){return x < 0 ? -x : x;}
inline LL mm(LL x, LL p){return x >= p ? x - p : x < 0 ? x + p : x;}
int v[200];
vector<P>ans;
priority_queue<P>que;
P lis[200];
int main()
{
int n;
while(~scanf("%d", &n)){
for(int i = 1; i <= n; ++i) scanf("%d", &v[i]);
ans.clear();
while(!que.empty()) que.pop();
P now;
bool flag = true, mu = false;
for(int i = 1; i <= n; ++i){
if(v[i]) que.push({v[i], i});
}
while(!que.empty() && flag){
now = que.top(); que.pop();
for(int i = 1; i <= now.fi; ++i){
if(que.empty()) flag = false;
else{
lis[i] = que.top();que.pop();
}
}
if(!mu && !que.empty()){
mu = true;
}
for(int i = 1; i <= now.fi; ++i){
ans.push_back({now.se, lis[i].se});
if(lis[i].fi > 1) que.push({lis[i].fi - 1, lis[i].se});
}
}
if(!flag) puts("IMPOSSIBLE");
else{
if(mu) puts("MULTIPLE");
else puts("UNIQUE");
printf("%d %d\n", n, ans.size());
for(int i = 0; i < ans.size(); ++i){
printf("%d ", ans[i].fi);
}
puts("");
for(int i = 0; i < ans.size(); ++i){
printf("%d ", ans[i].se);
}
puts("");
if(mu){
mu = false;
ans.clear();
for(int i = 1; i <= n; ++i) if(v[i]) que.push({v[i], i});
while(!que.empty() && flag){
now = que.top(); que.pop();
for(int i = 1; i <= now.fi; ++i){
lis[i] = que.top();que.pop();
}
if(!mu && !que.empty()){
lis[0] = que.top();
mu = true;
que.pop();
que.push(lis[now.fi]);
lis[now.fi] = lis[0];
}
for(int i = 1; i <= now.fi; ++i){
ans.push_back({now.se, lis[i].se});
if(lis[i].fi > 1) que.push({lis[i].fi - 1, lis[i].se});
}
}
printf("%d %d\n", n, ans.size());
for(int i = 0; i < ans.size(); ++i){
printf("%d ", ans[i].fi);
}
puts("");
for(int i = 0; i < ans.size(); ++i){
printf("%d ", ans[i].se);
}
puts("");
}
}
}
return 0;
}
H - Skycity
题目链接 https://vjudge.net/contest/228708#problem/H
I - LIKE vs CANDLE
题目链接 https://vjudge.net/contest/228708#problem/I
题解
树形dp, 0表示不翻, 1表示翻 然后xjb维护就可以了
代码
//#pragma comment(linker, "/stack:200000000")
//#pragma GCC optimize("Ofast,no-stack-protector")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//#pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#define fi first
#define se second
#define lson l,mid,o<<1
#define rson mid+1,r,o<<1|1
#define fio ios::sync_with_stdio(false);cin.tie(0)
using namespace std;
typedef long long LL;
typedef unsigned long long uLL;
typedef pair<int, int> P;
typedef pair<P, int> PII;
typedef pair<LL, int> PIII;
const LL INF = 0x3f3f3f3f;
const int N = 5e4 + 10;
const int M = 3e6 + 10;
const LL mod = 1e9 + 7;
const double PI=acos(-1);
inline LL ab(LL x){return x < 0 ? -x : x;}
inline LL mm(LL x, LL p){return x >= p ? x - p : x < 0 ? x + p : x;}
int n, x, y, flag;
vector<int>son[N];
struct Node{
int op, v;
int dp[2];
}node[N];
void dfs(int o){
flag ^= node[o].op;
if(flag) node[o].v = -node[o].v;
node[o].dp[0] = node[o].v, node[o].dp[1] = - node[o].v;
for(auto it : son[o]){
dfs(it);
node[o].dp[0] += max(node[it].dp[0], node[it].dp[1] - (node[it].op ? y : x));
node[o].dp[1] += max(node[it].dp[1], node[it].dp[0] - (node[it].op ? y : x));
}
flag ^= node[o].op;
}
int main()
{
while(~scanf("%d%d%d",&n, &x, &y)){
int v, f, s, p;
flag = 0;
for(int i = 0; i <= n; ++i) son[i].clear();
for(int i = 1; i <= n; ++i){
scanf("%d%d%d%d", &v, &f, &s, &p);
node[i].op = s;
if(p) node[i].v = -v;
else node[i].v = v;
son[f].push_back(i);
}
dfs(0);
if(node[0].dp[0] < 0) puts("HAHAHAOMG");
else printf("%d\n", node[0].dp[0]);
}
return 0;
}