2013 icpc 长沙 (5.12)

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;
}

J - Josephina and RPG

题目链接 https://vjudge.net/contest/228708#problem/J

K - Pocket Cube

题目链接 https://vjudge.net/contest/228708#problem/K

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值