2013 icpc 成都 (5.19)

A - Assignment For Princess

题目链接https://vjudge.net/contest/230171#problem/A

题解

xjb构造就可以了
先1到n两两连起来i, i+1的权值为i
接下来在满足条件的情况下连i, 1的边
然后在连其他的边就可以了

代码

//#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
using namespace std;
typedef long long LL;
typedef unsigned long long uLL;
typedef pair<int, int> P;
typedef pair<P, int> PII;
const LL INF = 0x3f3f3f3f;
const int N = 1e7 + 10;
const LL mod = 1e9 + 7;
const double PI=acos(-1);

queue<int>tot[3];
int sum[110];
int main()
{
    int T;
    scanf("%d", &T);
    for(int t = 1; t <= T; ++t){
        printf("Case #%d:\n", t);
        int n, m;
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= m; ++i) tot[i % 3].push(i);
        sum[1] = 0;
        for(int i = 1; i < n; ++i){
            printf("%d %d %d\n", i, i + 1, tot[i % 3].front());
            sum[i + 1] = (sum[i] + i) % 3;
            tot[i % 3].pop();
        }
        for(int i = n; i > 2; --i){
            if(tot[(3 - sum[i]) % 3].empty())    continue;
            printf("%d %d %d\n", i, 1, tot[(3 - sum[i]) % 3].front());
            tot[(3 - sum[i]) % 3].pop();
        }
        for(int i = 2; i < n; ++i){
            for(int j = i + 2; j <= n; ++j){
                if(tot[(sum[j] + 3 - sum[i]) % 3].empty())    continue;
                printf("%d %d %d\n", i, j, tot[(sum[j] + 3 - sum[i]) % 3].front());
                tot[(sum[j] + 3 - sum[i]) % 3].pop();
            }
        }
    }
    return 0;
}

B - Beautiful Soup

题目链接https://vjudge.net/contest/230171#problem/B

C - Clumsy Algorithm

题目链接https://vjudge.net/contest/230171#problem/C

题解

首先通过打表,发现题目中的条件等价于单调递减的子序列的长度小于3
然后就可以xjbg维护了啊

代码

//#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
using namespace std;
typedef long long LL;
typedef unsigned long long uLL;
typedef pair<int, int> P;
typedef pair<P, int> PII;
const LL INF = 0x3f3f3f3f;
const int N = 1e7 + 10;
const LL mod = 1e9 + 7;
const double PI=acos(-1);
inline int ab(int x){return x < 0 ? -x : x;}
inline int mm(int x, int p){return x >= p ? x - p : x < 0 ? x + p : x;}

int a[120];
int dp[120][120];
bool vis[120];
int main()
{
    int T, n, k;
    scanf("%d", &T);
    for(int t = 1; t <= T; ++t){
        scanf("%d%d", &n, &k);
        memset(dp, 0, sizeof dp);
        for(int i = 1; i <= k; ++i) scanf("%d", &a[i]);
        int now = 0;
        memset(vis, false, sizeof vis);
        vis[0] = true;
        bool flag = true;
        for(int i = 1; i <= k; ++i){
            if(a[i] > now)  now = a[i], vis[a[i]] = true;
            else{
                if(!vis[a[i] - 1])   flag = false;
                else    vis[a[i]] = true;
            }
        }
        printf("Case #%d: ", t);
        dp[now][k] = flag;
        for(int i = now + 1; i <= n; ++i){
            dp[i][k] = flag;
            for(int j = k + 1; j < i; ++j)
                dp[i][j] = mm(dp[i][j - 1] + dp[i - 1][j], mod);
        }
        int ssum = 0;
        for(int i = k; i <= n; ++i)  ssum = mm(dp[n][i] + ssum, mod);
        printf("%d\n", ssum);
    }
    return 0;
}

D - Dinner Coming Soon

题目链接https://vjudge.net/contest/230171#problem/D

题解

暴力的dp去维护,按时间循序,因为每一次位置的变化时间必定增加,然后注意结束位置和一些细节

代码

//#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<int, P> PII;
typedef pair<LL, int> PIII;
const LL INF = 0x3f3f3f3f;
const int N = 1e5 + 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 mp[210][10];
LL dp[210][10][210][10];
vector<PII>son[210];

int main()
{

    int Cas, n, m, b, k, r, t, u, v, c_t, c_c;
    scanf("%d", &Cas);
    for(int cas = 1; cas <= Cas; ++cas){
        scanf("%d%d%d%d%d%d", &n, &m, &b, &k, &r, &t);
        for(int i = 0; i < k; ++i)
            for(int j = 1; j <= n; ++j)
                scanf("%d", &mp[j][i]);
        for(int i = 1; i <= n; ++i) son[i].clear();
        for(int i = 1; i <= m; ++i){
            scanf("%d%d%d%d", &u, &v, &c_t, &c_c);
            son[u].push_back({v, {c_t, c_c}});
        }
        memset(dp, -1, sizeof dp);
        dp[1][0][0][0] = r;

        LL ans = -1;
        for(int h = 0; h <= t; ++h){
            for(int now = 1; now < n; ++now){
                for(int i = 0; i < k; ++i){
                    if(now != 1){
                        for(int j = 0; j < b; ++j){
                            if(dp[now][i][h][j + 1] >= 0 && dp[now][i][h][j] < dp[now][i][h][j + 1] + mp[now][i])
                              dp[now][i][h][j] = dp[now][i][h][j + 1] + mp[now][i];
                        }
                        for(int j = b; j > 0; --j){
                            if(dp[now][i][h][j - 1] >= mp[now][i] && dp[now][i][h][j] < dp[now][i][h][j - 1] - mp[now][i])
                               dp[now][i][h][j] = dp[now][i][h][j - 1] - mp[now][i];
                        }
                    }

                    for(int j = 0; j <= b; ++j){
                        if(dp[now][i][h][j] == -1)  continue;
                        if(dp[now][i][h][j] > dp[now][(i + 1) %k][h + 1][j])
                            dp[now][(i + 1) %k][h + 1][j] = dp[now][i][h][j];
                        for(auto it : son[now])
                            if(h + it.se.fi <= t && dp[now][i][h][j] - it.se.se > dp[it.fi][i][h + it.se.fi][j])
                             dp[it.fi][i][h + it.se.fi][j] = dp[now][i][h][j] - it.se.se;
                    }

                }
            }
            ans = max(ans, dp[n][0][h][0]);
        }

        printf("Case #%d: ", cas);
        if(ans == -1)   printf("Forever Alone\n");
        else    printf("%lld\n", ans);

    }
    return 0;
}
/*
2
4 4
1 2 1
2 3 1
3 4 1
1 4 0
5 6
1 2 1
1 3 1
1 4 1
1 5 1
3 5 1
4 2 1
*/

E - Exhausted Robot

题目链接https://vjudge.net/contest/230171#problem/E

F - Fibonacci Tree

题目链接https://vjudge.net/contest/230171#problem/F

题解

先判断图是否联通
然后用黑边去连看最少还需要多少条边
然后用白边去连看最多能用多少条边
然后在判一判就可以了

代码

//#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 = 1e5 + 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, m;
P edge[2][N];
int tot[2];
int fa[N];
int find(int x){
    return fa[x] == x ? x : fa[x] = find(fa[x]);
}
bool check1(){
    for(int i = 1; i <= n; ++i) fa[i] = i;
    int u, v;
    for(int i = 0; i < 2; ++i)
        for(int j = 1; j <= tot[i]; ++j){
            u = find(edge[i][j].fi), v = find(edge[i][j].se);
            fa[u] = v;
        }
    int res = 0;
    for(int i = 1; i <= n; ++i) res += (fa[i] == i);
    return res == 1;
}
int fib[N];
int check2(){
    for(int i = 1; i <= n; ++i) fa[i] = i;
    int u, v;
    for(int i = 0; i <= 0; ++i)
        for(int j = 1; j <= tot[i]; ++j){
            u = find(edge[i][j].fi), v = find(edge[i][j].se);
            fa[u] = v;
        }
    int res = 0;
    for(int i = 1; i <= n; ++i) res += (fa[i] == i);
    return res;
}
int check3(){
    for(int i = 1; i <= n; ++i) fa[i] = i;
    int u, v;
    int res = 0;
    for(int i = 1; i <= 1; ++i)
        for(int j = 1; j <= tot[i]; ++j){
            u = find(edge[i][j].fi), v = find(edge[i][j].se);
            if(u != v)  res++, fa[u] = v;
        }
    return res;
}
int main()
{
    int cnt = 2;
    fib[1] = 1, fib[2] = 2;
    for(int i = 3; fib[i - 1] < 1e6; ++i)   fib[i] = fib[i - 1] + fib[i - 2], cnt++;
//    cout << cnt << endl;
    int t, u, v, op;
    scanf("%d", &t);
    for(int cas = 1; cas <= t; ++cas){
        printf("Case #%d: ", cas);
        scanf("%d%d", &n, &m);
        tot[0] = tot[1] = 0;
        for(int i = 1; i <= m; ++i){
            scanf("%d%d%d", &u, &v, &op);
            edge[op][++tot[op]] = {u, v};
        }
        if(check1()){
            int now = check2() - 1;
            int id = lower_bound(fib + 1, fib + cnt + 1, now) - fib;
//            cout << now << " " << fib[id] <<  check3() << endl;
            if(check3() >= fib[id])  puts("Yes");
            else    puts("No");
        }
        else{
            puts("No");
        }
    }
    return 0;
}
/*
2
4 4
1 2 1
2 3 1
3 4 1
1 4 0
5 6
1 2 1
1 3 1
1 4 1
1 5 1
3 5 1
4 2 1
*/

G - GRE Words Revenge

题目链接https://vjudge.net/contest/230171#problem/G

题解

ac自动机加二进制分组(名字口胡的)

代码

//#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
using namespace std;
typedef long long LL;
typedef unsigned long long uLL;
typedef pair<int, int> P;
typedef pair<int, P> PII;
const LL INF = 0x3f3f3f3f;
const int N = 1e7 + 10;
const LL mod = 1e9 + 7;
const double PI=acos(-1);


struct Trie{
    static const int kN = N;
    static const int chN = 2;
    int next[kN][chN], fail[kN], tot = 0, root[30], mark[kN], mark1[kN], cnt = 0, si[30];
    void init(){
        cnt = tot = 0;
    }
    inline int newcode(){
        tot++;
        memset(next[tot], 0, sizeof(next[tot]));
        mark[tot] = 0;
        return tot;
    }
    void build(int x){
        queue <int> que;
        que.push(x);
        fail[x] = 0;
        mark1[x] = 0;
        int pos, u, v;
        while(!que.empty()){
            pos = que.front(); que.pop();
            for(int i = 0; i < chN; ++ i){
                if(!next[pos][i])   continue;
                u = fail[pos], v = next[pos][i];
                while(u && !next[u][i]) u = fail[u];
                fail[v] = u ? next[u][i] : x;
                que.push(v);
                mark1[v] = mark1[fail[v]] + mark[v];
            }
        }
    }
    void add(char s[], char ch){
        root[++cnt] = newcode(), si[cnt] = 1;
        int pos = root[cnt];
        for(int i = 0; s[i]; ++ i){
            if(!next[pos][s[i]-ch]) next[pos][s[i]-ch] = newcode();
            pos = next[pos][s[i]-ch];
        }
        mark[pos]++;
        while(si[cnt] == si[cnt - 1]){
            unite(root[cnt - 1], root[cnt]);
            si[--cnt] <<= 1;
        }
        build(root[cnt]);
    }
    LL query(char s[], char ch){
        int pos;
        LL ret = 0;
        for(int id = 1; id <= cnt; ++id){
            pos = root[id];
            for(int i = 0; s[i]; ++ i){
                while(pos && !next[pos][s[i]-ch])   pos = fail[pos];
                pos = pos ? next[pos][s[i]-ch] : root[id];
                ret += mark1[pos];
            }
        }
        return ret;
    }
    void unite(int u, int v){
        mark[u] += mark[v];
        for(int i = 0; i < chN; ++i){
            if(!next[u][i] || !next[v][i])   next[u][i] += next[v][i];
            else   unite(next[u][i], next[v][i]);
        }
    }
}ac;
char s[N];
set<uLL>st;
int main()
{
    int T;
    scanf("%d", &T);
    uLL v;
    for(int t = 1; t <= T; ++t){
        int n, now;
        LL res = 0;
        ac.init();
        st.clear();
        printf("Case #%d:\n", t);
        scanf("%d", &n);
        for(int i = 1; i <= n; ++i){
            scanf("%s", s);
            int len = strlen(s);
            now = res % (len - 1);
            reverse(s + 1, s + len);
            reverse(s + 1, s + len - now);
            reverse(s + len - now, s + len);
            if(s[0] == '+'){
                v = 1;
                for(int i = 1; s[i]; ++i)   v = v * 31 + s[i] - '0';
                if(st.find(v) != st.end())  continue;
                else{
                    st.insert(v);
                    ac.add(s + 1, '0');
                }
            }
            else{
                res = ac.query(s + 1, '0');
                printf("%lld\n", res);
            }
        }
    }
    return 0;
}

H - Hard Disk Drive

题目链接https://vjudge.net/contest/230171#problem/H

I - ICPC Ranking

题目链接https://vjudge.net/contest/230171#problem/I

J - Just Random

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值