2012 Regional Changchun Site

部分题目:

比赛队友过掉的题目,没有过掉但有可能过掉的题目。。。

B:

傻逼2-sat题,据说是道poj原题,共有31位,对每一位进行2-sat判一下。fuck,一个很坑人的trick,给的b[][]不一定是合法的。如果不合法,直接输出NO

View Code
//#pragma comment(linker,"/STACK:327680000,327680000")
#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
#include <string>
#include <set>
#include <functional>
#include <numeric>
#include <sstream>
#include <stack>
#include <map>
#include <queue>

#define CL(arr, val) memset(arr, val, sizeof(arr))
#define REP(i, n)for((i) = 0; (i) < (n); ++(i))
#define FOR(i, l, h)for((i) = (l); (i) <= (h); ++(i))
#define FORD(i, h, l)for((i) = (h); (i) >= (l); --(i))
#define L(x)(x) << 1
#define R(x)(x) << 1 | 1
#define MID(l, r)(l + r) >> 1
#define Min(x, y)x < y ? x : y
#define Max(x, y)x < y ? y : x
#define E(x)(1 << (x))
#define iabs(x) (x) < 0 ? -(x) : (x)
#define OUT(x)printf("%I64d\n", x)
#define lowbit(x)(x)&(-x)
#define Read()freopen("data.in", "r", stdin)
#define Write()freopen("data.out", "w", stdout);

const double eps = 1e-8;
typedef long long LL;
const int inf = ~0u>>2;

using namespace std;

const int maxn = 1024;

struct node {
    int to;
    int next;
} g[maxn*maxn];

int head[maxn], t;
int n, b[maxn>>1][maxn>>1];

int scc[maxn], dfn[maxn], low[maxn], s[maxn];
bool vis[maxn];

int ind, cnt, top;

void init() {
    for(int i = 0; i < maxn; i++) {
         scc[i] = dfn[i] = low[i] = vis[i] = 0;
         head[i] = -1;
    }
    ind = cnt = top = t = 0;
}

void add(int u, int v) {
    g[t].to = v; g[t].next = head[u]; head[u] = t++;
}

void build_mp(int p) {
    int i, j;
    init();
    //printf("%d\n", p);
    for(i = 0; i < n; ++i) {
        for(j = 0; j < n; ++j) {
            if(i == j)  continue;
            if(i%2 == 1 && j%2 == 1) {
                if(b[i][j]&(1<<p)) {
                    add(i, j + n);
                    add(j, i + n);
                } else {
                    add(i + n, i);
                    add(j + n, j);
                }
            } else if(i%2 == 0 && j%2 == 0) {
                if(b[i][j]&(1<<p)) {
                    add(i, i + n);
                    add(j, j + n);
                } else {
                    add(i + n, j);
                    add(j + n, i);
                }
            } else {
                if(b[i][j]&(1<<p)) {
                    add(i, j + n);
                    add(j, i + n);
                    add(i + n, j);
                    add(j + n, i);
                } else {
                    add(i, j);
                    add(j, i);
                    add(i + n, j + n);
                    add(j + n, i + n);
                }
            }
        }
    }
}

 void dfs(int u) {
     int v, i;
     dfn[u] = low[u] = ++ind;
     s[++top] = u; vis[u] = true;
     for(i = head[u]; i != -1; i = g[i].next) {
         v = g[i].to;
         if(!dfn[v]) {
             dfs(v);
             low[u] = min(low[u], low[v]);
         } else if(vis[v]) {
             low[u] = min(low[u], dfn[v]);
         }
     }
     if(dfn[u] == low[u]) {
         //puts("here");
         cnt++;
         do {
             v = s[top--];
            //printf("%d %d\n", v, cnt);
             scc[v] = cnt;
             vis[v] = false;
         } while(v != u);
     }
 }

 void tarjan(int n) {
     for(int i = 0; i < n; ++i) {
         if(!dfn[i])    dfs(i);
     }
 }

 bool solve(int n) {
     tarjan(n<<1);
     for(int i = 0; i < n; ++i) {
        if(scc[i] == scc[i+n])    return false;
     }
     return true;
 }

bool DO() {
    int i, j, p;

    for(i = 0; i < n; ++i) {    //trick
        for(j = 0; j < n; ++j) {
            if(i == j && b[i][j] != 0)  return false;
            if(b[i][j] != b[j][i])  return false;
        }
    }

    for(p = 0; p < 31; ++p) {
        build_mp(p);
        if(!solve(n))    return false;
    }
    return true;
}

int main() {
    //freopen("data.in", "r", stdin);

    int i, j;
    while(~scanf("%d", &n)) {
        for(i = 0; i < n; ++i) {
            for(j = 0; j < n; ++j) {
                scanf("%d", &b[i][j]);
            }
        }
        if(DO())    puts("YES");
        else    puts("NO");
    }
    return 0;
}

 

C:

乱搞题,比赛的时候我搞的,弄清楚题意就会发现这是一道水题。。。

View Code
//#pragma comment(linker,"/STACK:327680000,327680000")
#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
#include <string>
#include <set>
#include <functional>
#include <numeric>
#include <sstream>
#include <stack>
#include <map>
#include <queue>

#define CL(arr, val) memset(arr, val, sizeof(arr))
#define REP(i, n)for((i) = 0; (i) < (n); ++(i))
#define FOR(i, l, h)for((i) = (l); (i) <= (h); ++(i))
#define FORD(i, h, l)for((i) = (h); (i) >= (l); --(i))
#define L(x)(x) << 1
#define R(x)(x) << 1 | 1
#define MID(l, r)(l + r) >> 1
#define Min(x, y)x < y ? x : y
#define Max(x, y)x < y ? y : x
#define E(x)(1 << (x))
#define iabs(x) (x) < 0 ? -(x) : (x)
#define OUT(x)printf("%I64d\n", x)
#define lowbit(x)(x)&(-x)
#define Read()freopen("data.in", "r", stdin)
#define Write()freopen("data.out", "w", stdout);

const double eps = 1e-8;
typedef long long LL;
const int inf = ~0u>>2;

using namespace std;

const int maxn = 200010;

LL cnt[maxn];
int parent[maxn];
LL tol[maxn];

struct node {
    int u, v, w;
    bool operator < (const node cmp) const {
        return this->w > cmp.w;
    }
}p[maxn];

int find(int x) { return parent[x] == x ? x : (parent[x] = find(parent[x]));}

int main() {
   // freopen("data.in", "r", stdin);

    int n, i,a , b, c;
    while(~scanf("%d", &n)) {
        for(i = 0; i < n - 1; ++i) {
            scanf("%d%d%d", &p[i].u, &p[i].v, &p[i].w);
        }
        sort(p, p + n - 1);

        for(i = 0; i <= n; ++i) {
            cnt[i] = 1; tol[i] = 0; parent[i] = i;
        }

        for(i = 0; i < n - 1; ++i) {
            a = p[i].u;
            b = p[i].v;
            c = p[i].w;
            a = find(a); b = find(b);
            if(a == b)  continue;
            LL t1 = cnt[a]*c + tol[b];
            LL t2 = cnt[b]*c + tol[a];
            if(t1 >= t2) {
                parent[a] = b;
                tol[b] = t1;
                cnt[b] += cnt[a];
            } else {
                parent[b] = a;
                tol[a] = t2;
                cnt[a] += cnt[b];
            }
        }
        LL ans = tol[1];
        for(i = 2; i <= n; ++i) {
            ans = max(ans, tol[i]);
        }
        printf("%lld\n", ans);
    }
    return 0;
}

H:

 我太弱了,比赛的时候队友跟我讨论。。。我没看懂。。。对不起队友了。。。T_T

发现两个点dp就很明确了:

1、Ai是m的约数。

2、LCM(Ai, Aj)也是m的约数。

把所有m的约数找出来,状态压缩dp。。。

View Code
//#pragma comment(linker,"/STACK:327680000,327680000")
#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
#include <string>
#include <set>
#include <functional>
#include <numeric>
#include <sstream>
#include <stack>
#include <map>
#include <queue>

#define CL(arr, val) memset(arr, val, sizeof(arr))
#define REP(i, n)for((i) = 0; (i) < (n); ++(i))
#define FOR(i, l, h)for((i) = (l); (i) <= (h); ++(i))
#define FORD(i, h, l)for((i) = (h); (i) >= (l); --(i))
#define L(x)(x) << 1
#define R(x)(x) << 1 | 1
#define MID(l, r)(l + r) >> 1
#define Min(x, y)x < y ? x : y
#define Max(x, y)x < y ? y : x
#define E(x)(1 << (x))
#define iabs(x) (x) < 0 ? -(x) : (x)
#define OUT(x)printf("%I64d\n", x)
#define lowbit(x)(x)&(-x)
#define Read()freopen("data.in", "r", stdin)
#define Write()freopen("data.out", "w", stdout);

const double eps = 1e-8;
typedef long long LL;
const int inf = ~0u>>2;

using namespace std;

const int N = 1024;
const int MOD = 1e9+7;

int dp[2][N][110];
int pnum[N];
int pos[N];
int LCM[N][N];

int gcd(int a, int b) {
    return b == 0 ? a : gcd(b, a%b);
}

int lcm(int a, int b) {
    return a/gcd(a, b)*b;
}

int main() {
    //freopen("data.in", "r", stdin);

    int i, j, k, l;

    for(i = 1; i < N; ++i) {
        for(j = i; j < N; ++j) {
            LCM[j][i] = LCM[i][j] = lcm(i, j);
        }
    }

    int n, m, K, cnt;
    while(~scanf("%d%d%d", &n, &m, &K)) {
        CL(pos, -1);
        cnt = 0;
        for(i = 1; i <= m; ++i) {
            if(m%i == 0) {
                pnum[cnt] = i;
                pos[i] = cnt++;
            }
        }

        CL(dp, -1);

        for(i = 0; i < cnt; ++i) {
            dp[1][pnum[i]][pos[pnum[i]]] = 1;
        }


        for(k = 2; k <= K; ++k) {
            for(i = k - 1; i <= n; ++i) {   //Ai are all positive numbers
                for(j = 0; j < cnt; ++j) {

                    if(dp[(k-1)&1][i][j] == -1) continue;

                    for(l = 0; l < cnt && i + pnum[l] <= n; ++l) {
                        int pp = LCM[pnum[j]][pnum[l]];
                        if(pos[pp] == -1)   continue;
                        pp = pos[pp];

                        if(dp[k&1][i + pnum[l]][pp] == -1) dp[k&1][i + pnum[l]][pp] = dp[(k-1)&1][i][j];
                        else    dp[k&1][i + pnum[l]][pp] += dp[(k-1)&1][i][j];

                        if(dp[k&1][i + pnum[l]][pp] >= MOD)   dp[k&1][i + pnum[l]][pp] -= MOD;
                    }
                }
            }
            CL(dp[(k-1)&1], -1);
        }
        int ans;
        if(dp[K&1][n][cnt-1] == -1)   ans = 0;
        else    ans = dp[K&1][n][cnt-1];

        printf("%d\n", ans);
    }
    return 0;
}

 

K:

乱搞,枚举r,二分k,注意过程会超long long ,比赛的时候跪了3次。。

View Code
//#pragma comment(linker,"/STACK:327680000,327680000")
#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
#include <string>
#include <set>
#include <functional>
#include <numeric>
#include <sstream>
#include <stack>
#include <map>
#include <queue>

#define CL(arr, val) memset(arr, val, sizeof(arr))
#define REP(i, n)for((i) = 0; (i) < (n); ++(i))
#define FOR(i, l, h)for((i) = (l); (i) <= (h); ++(i))
#define FORD(i, h, l)for((i) = (h); (i) >= (l); --(i))
#define L(x)(x) << 1
#define R(x)(x) << 1 | 1
#define MID(l, r)(l + r) >> 1
#define Min(x, y)x < y ? x : y
#define Max(x, y)x < y ? y : x
#define E(x)(1 << (x))
#define iabs(x) (x) < 0 ? -(x) : (x)
#define OUT(x)printf("%I64d\n", x)
#define lowbit(x)(x)&(-x)
#define Read()freopen("data.in", "r", stdin)
#define Write()freopen("data.out", "w", stdout);

const double eps = 1e-8;
typedef long long LL;
const int inf = ~0u>>2;

using namespace std;


int dblcmp(double x) {
    if(x > eps) return 1;
    else if(x < -eps)   return -1;
    return 0;
}

LL search(LL n, LL x) {
    LL l = 0, r = n;
    LL mid;

    double sum, tp;
    int cx;
    while(l <= r) {
        mid = MID(l, r);
        sum = 0; tp = mid; cx = 0;

        for( ; cx < x && dblcmp(sum - n) == -1; cx++, sum += tp, tp *= mid);

        if(cx < x) {
            r = mid - 1;
            continue;
        }

        if(dblcmp(sum - n) == 0 || dblcmp(sum - n + 1) == 0)    return mid;
        else if(dblcmp(sum - n) == -1)  l = mid + 1;
        else    r = mid - 1;
    }
    return -1;
}

int main() {
    //Read();

    LL n, r, k, tmp;
    LL ar, ak;
    while(~scanf("%lld", &n)) {
        tmp = -1;
        for(r = 1; r <= 60; ++r) {
            k = search(n, r);
            if(k == -1) continue;
            if(r*k < tmp || tmp == -1) {
                tmp = r*k;
                ar = r; ak = k;
            }
        }
        printf("%lld %lld\n", ar, ak);
    }
    return 0;
}

 

 

Oooooooooooooooooooooooorz 

 

 

 

posted @ 2012-10-18 16:23  AC_Von  阅读(224)  评论(0编辑  收藏  举报