下雪了

Kattis secretchamber – Secret Chamber at Mount Rushmore(弗洛伊德求闭包/弗洛伊德模板)

WF的题,放弃好了。

emmm,一开始是想用字典树什么的,就没去看。后来发现,我们要把一个点与另一个点连起来,那就想到如果把它们看成26*26的图,说不定就好了呢?题目范围给的很小,那么n^3是绝对不会超时的,所以就用Floyd来做,果然不出所料。

AC代码:

#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<string>
#include<vector>
#include<cstdio>
#include<stack>
#include<cmath>
#include<ctime>
#include<queue>
#include<deque>
#include<list>
#include<map>
#define int long long
#define ffor(i, a, b) for(ll i = a; i <= b; i++)
#define rfor(i, a, b) for(ll i = a; i >= b; i--)
#define mes(a,b) memset(a, b, sizeof(a))
#define cos(x) cos(x*PI/180.0)
#define sin(x) sin(x*PI/180.0)
#define stop system("pause")
#define see(s,x) cout<<(s)<<'='<<(x)<<endl
#define IMAX 0x7fffffff
#define PI 3.141592654
#define INF 0x3f3f3f3f
#define eps 1e-6
#define lowbit(x) (x&(-x))
typedef long long ll;
ll mod;
ll max(ll a, ll b) { return(a > b) ? a : b; }
ll min(ll a, ll b) { return(a < b) ? a : b; }
using namespace std;

int mp[30][30];

int main()
{
    int n, m;
    while (cin >> n >> m)
    {
        getchar();
        ffor(i, 0, 26)
        {
            ffor(k, 0, 26)
                mp[i][k] = 99;
            mp[i][i] = 0;
        }
        ffor(i, 1, n)
        {
            char x, y;
            scanf("%c %c%*c", &x, &y);
            mp[x - 'a'][y - 'a'] = 0;
        }
        ffor(j, 0, 26)
        {
            ffor(i, 0, 26)
            {
                ffor(k, 0, 26)
                    mp[i][k] = min(mp[i][k], mp[i][j] + mp[j][k]);
            }
        }
        ffor(i, 1, m)
        {
            char s1[60], s2[60];
            cin >> s1 >> s2;
            int l1 = strlen(s1);
            int l2 = strlen(s2);
            bool ok = true;
            if (l1 == l2)
            {
                ffor(i, 0, l1 - 1)
                {
                    int x = s1[i] - 'a';
                    int y = s2[i] - 'a';
                    if (mp[x][y] != 0)
                    {
                        ok = false;
                        break;
                    }
                }
            }
            else ok = false;
            if (ok) cout << "yes" << endl;
            else cout << "no" << endl;
        }
    }
}

 

HDU1166 – 敌兵布阵(线段树模板)

重新写了一发模板(乖乖地push_up和push_down了……)

AC代码:

#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<string>
#include<vector>
#include<cstdio>
#include<stack>
#include<cmath>
#include<ctime>
#include<queue>
#include<deque>
#include<list>
#include<map>
#define int long long
#define ffor(i, a, b) for(ll i = a; i <= b; i++)
#define rfor(i, a, b) for(ll i = a; i >= b; i--)
#define mes(a,b) memset(a, b, sizeof(a))
#define cos(x) cos(x*PI/180.0)
#define sin(x) sin(x*PI/180.0)
#define stop system("pause")
#define see(s,x) cout<<(s)<<'='<<(x)<<endl
#define IMAX 0x7fffffff
#define PI 3.141592654
#define INF 0x3f3f3f3f
#define eps 1e-6
#define lowbit(x) (x&(-x))
typedef long long ll;
ll mod;
ll max(ll a, ll b) { return(a > b) ? a : b; }
ll min(ll a, ll b) { return(a < b) ? a : b; }
using namespace std;

struct unit
{
    int l;
    int r;
    int sum;
    int lazy;
};

unit tab[50005 << 2];
int num[50005];
int rt;
int cnt;

void pushdown(int x,int l,int r)
{
    if (tab[x].lazy)
    {
        tab[tab[x].l].lazy += tab[x].lazy;
        tab[tab[x].r].lazy += tab[x].lazy;
        tab[tab[x].l].sum += tab[x].lazy * (r - l + 1);//要看情况乘多少,例如取min的话只乘1,总和就要乘上区间长度
        tab[tab[x].r].sum += tab[x].lazy * (r - l + 1);
        tab[x].lazy = 0;
    }
}

void pushup(int x)
{
    tab[x].sum = tab[tab[x].l].sum + tab[tab[x].r].sum;
}

void build(int& x, int l, int r)
{
    x = ++cnt;
    tab[x].lazy = 0;
    if (l == r)
    {
        tab[x].sum = num[l];
        return;
    }
    int m = (l + r) >> 1;
    build(tab[x].l, l, m);
    build(tab[x].r, m + 1, r);
    pushup(x);
}

void update(int x, int L, int R, int l, int r,int value)
{
    if (L <= l && R >= r)
    {
        tab[x].sum += value * (r - l + 1);
        tab[x].lazy += value;
        return;
    }
    pushdown(x, l, r);
    int m = (l + r) >> 1;
    if (L <= m) update(tab[x].l, L, R, l, m, value);
    if (R > m) update(tab[x].r, L, R, m + 1, r, value);
    pushup(x);
}

int check(int x, int L, int R, int l, int r)
{
    if (L <= l && R >= r)
        return tab[x].sum;
    pushdown(x, l, r);
    int m = (l + r) >> 1;
    int sum = 0;
    if (L <= m) sum += check(tab[x].l, L, R, l, m);
    if (R > m) sum += check(tab[x].r, L, R, m + 1, r);
    pushup(x);
    return sum;
}


signed main()
{
    int T;
    cin >> T;
    ffor(c, 1, T)
    {
        cnt = 0;
        int n;
        cin >> n;
        ffor(i, 1, n)
            scanf("%lld", &num[i]);
        build(rt, 1, n);
        printf("Case %lld:\n", c);
        while (true)
        {
            char s[10];
            int x, y;
            scanf("%s", s);
            if (s[0] != 'E')
            {
                scanf("%lld%lld", &x, &y);
                if (s[0] == 'A')
                    update(rt, x, x, 1, n, y);
                else if (s[0] == 'S')
                    update(rt, x, x, 1, n, -y);
                else if (s[0] == 'Q')
                    printf("%lld\n", check(rt, x, y, 1, n));
            }
            else break;
        }
    }
    return 0;
}

 

洛谷P3384 – 树链剖分(模板)

树链剖分模板题emmm

(又因为int什么的wa了啊….以后#define int long long 好了……)

AC代码:

#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<string>
#include<vector>
#include<cstdio>
#include<stack>
#include<cmath>
#include<ctime>
#include<queue>
#include<deque>
#include<list>
#include<map>
#define int long long
#define ffor(i, a, b) for(int i = a; i <= b; i++)
#define rfor(i, a, b) for(int i = a; i >= b; i--)
#define mes(a,b) memset(a, b, sizeof(a))
#define cos(x) cos(x*PI/180.0)
#define sin(x) sin(x*PI/180.0)
#define stop system("pause")
#define see(s,x) cout<<(s)<<'='<<(x)<<endl
#define IMAX 0x7fffffff
#define PI 3.141592654
#define INF 0x3f3f3f3f
#define eps 1e-6
#define lowbit(x) (x&(-x))
typedef long long ll;
ll mod;
ll max(ll a, ll b) { return(a > b) ? a : b; }
ll min(ll a, ll b) { return(a < b) ? a : b; }
using namespace std;

struct unit
{
    int l;
    int r;
    ll sum;
    ll lazy;
};
unit tab[100005<<2];

vector<int> G[100005];
int fa[100005];
int dep[100005];
int sz[100005];
int rk[100005];
int id[100005];
int top[100005];
int son[100005];
int w[100005];

int n, q, rt, root;
int cnt;

void dfs1(int x, int f, int d)//处理出fa、dep
{
    dep[x] = d;
    fa[x] = f;
    sz[x] = 1;
    int maxson = -1;
    for (auto i : G[x])
    {
        if (i == f)continue;
        dfs1(i, x, d + 1);
        sz[x] += sz[i];
        if (sz[i] > maxson)
        {
            son[x] = i;
            maxson = sz[i];
        }
    }
}

void dfs2(int x, int t)//处理出rk、top、id
{
    id[x] = ++cnt;
    rk[cnt] = w[x];
    top[x] = t;
    if (!son[x])
        return;
    dfs2(son[x], t);
    for (auto i:G[x]) 
    {
        if (i != fa[x] && i != son[x])
            dfs2(i, i);
    }
}

void build(int &x,int l,int r)
{
    x = ++cnt;
    tab[x].lazy = 0;
    if (l == r)
    {
        tab[x].sum = rk[l] % mod;
        return;
    }
    int m = (l + r) >> 1;
    build(tab[x].l, l, m);
    build(tab[x].r, m + 1, r);
    tab[x].sum = (tab[tab[x].l].sum + tab[tab[x].r].sum) % mod;
}

void update(int x, int L, int R, int l, int r, ll value)// 汇总子节点的时候,要注意加上自己的lazy
{
    if (L <= l && R >= r)
    {
        tab[x].sum = (tab[x].sum + (r - l + 1) * value) % mod;
        tab[x].lazy += value;
        return;
    }
    int m = (l + r) >> 1;
    if (L <= m) update(tab[x].l, L, R, l, m, value);
    if (R > m) update(tab[x].r, L, R, m + 1, r, value);
    tab[x].sum = (tab[tab[x].l].sum + tab[tab[x].r].sum%mod + (tab[x].lazy * (r - l + 1))%mod) % mod;
}

ll check(int x, int L, int R, int l, int r, ll add)// 用add把每一层的lazy相加(*很重要!*)
{
    if (L <= l && R >= r)
        return (tab[x].sum + add * (r - l + 1)) % mod;
    int m = (l + r) >> 1;
    ll sum = 0;
    if (L <= m) sum = (sum + check(tab[x].l, L, R, l, m, (add + tab[x].lazy)%mod)) % mod;
    if (R > m) sum = (sum + check(tab[x].r, L, R, m + 1, r, (add + tab[x].lazy)%mod)) % mod;
    return sum;
}

void lpls(int x,int y,int z)
{
    z %= mod;
    while (top[x] != top[y])
    {
        if (dep[top[x]] < dep[top[y]])
            swap(x, y);
        update(rt, id[top[x]], id[x], 1, n, z);
        x = fa[top[x]];
    }
    if (dep[x] > dep[y])
        swap(x, y);
    update(rt, id[x], id[y], 1, n, z);
}

ll lcheck(int x, int y)
{
    ll res = 0;
    while (top[x] != top[y])
    {
        if (dep[top[x]] < dep[top[y]])
            swap(x, y);
        res = (res + check(rt, id[top[x]], id[x], 1, n, 0)) % mod;
        x = fa[top[x]];
    }
    if (dep[x] > dep[y])
        swap(x, y);
    res = (res + check(rt, id[x], id[y], 1, n, 0)) % mod;
    return res;
}

void spls(int x, int y)
{
    update(rt, id[x], id[x] + sz[x] - 1, 1, n, y);
}

ll scheck(int x)
{
    return check(rt, id[x], id[x]+sz[x]-1, 1, n, 0) % mod;
}

signed main()
{
    cin >> n >> q >> root >> mod;
    ffor(i, 1, n)
        scanf("%lld", &w[i]);
    ffor(i, 1, n - 1)
    {
        int x, y;
        scanf("%lld%lld", &x, &y);
        G[x].push_back(y);
        G[y].push_back(x);
    }
    cnt = 0;
    dfs1(root, 0, 1);
    dfs2(root, root);
    cnt = 0;
    build(rt, 1, n);
    ffor(i, 1, q)
    {
        int o;
        scanf("%lld", &o);
        int x, y, z;
        switch (o)
        {
        case 1:
            scanf("%lld%lld%lld", &x, &y, &z);
            lpls(x, y, z);
            break;
        case 2:
            scanf("%lld%lld", &x, &y);
            printf("%lld\n",lcheck(x, y));
            break;
        case 3:
            scanf("%lld%lld", &x, &y);
            spls(x, y);
            break;
        default:
            scanf("%lld", &x);
            printf("%lld\n", scheck(x));
            break;
        }
    }
    return 0;
}

 

洛谷P3385 -【模板】负环(SPFA)

SPFA判断负环的模板题,利用BFS来遍历并标记入队的次数,如果大于n次则说明出现了负环。

AC代码:

#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<string>
#include<vector>
#include<cstdio>
#include<stack>
#include<cmath>
#include<ctime>
#include<queue>
#include<deque>
#include<list>
#include<map>
#define ffor(i, a, b) for(int i = a; i <= b; i++)
#define rfor(i, a, b) for(int i = a; i >= b; i--)
#define mes(a,b) memset(a, b, sizeof(a))
#define cos(x) cos(x*PI/180.0)
#define sin(x) sin(x*PI/180.0)
#define stop system("pause")
#define see(s,x) cout<<(s)<<'='<<(x)<<endl
#define IMAX 0x7fffffff
#define PI 3.141592654
#define INF 0x3f3f3f3f
#define eps 1e-6
#define lowbit(x) (x&(-x))
typedef long long ll;
const ll mod = (ll)1e9 + 7;
ll max(ll a, ll b) { return(a > b) ? a : b; }
ll min(ll a, ll b) { return(a < b) ? a : b; }
using namespace std;

struct unit
{
    int to;
    int w;
    unit() {};
    unit(int a, int b) :to(a), w(b) {};
};

vector<unit> G[3005];
int dis[3005];
int cnt[3005];
bool v[3005];

bool spfa(int s,int n)
{
    dis[s] = 0;
    queue<int> q;
    q.push(s);
    cnt[s]++;
    while (!q.empty())
    {
        int f = q.front();
        q.pop();
        v[f] = false;
        for (vector<unit>::iterator it = G[f].begin(); it != G[f].end(); it++)
        {
            unit u = *it;
            if (dis[f] + u.w < dis[u.to])
            {
                dis[u.to] = dis[f] + u.w;
                if (!v[u.to])
                {
                    q.push(u.to);
                    v[u.to] = true;
                    cnt[u.to]++;
                    if (cnt[u.to] > n)
                        return true;
                }
            }
        }
    }
    return false;
}

int main()
{
    int T;
    cin >> T;
    while (T--)
    {
        int n, m;
        cin >> n >> m;
        ffor(i, 1, n)
        {
            cnt[i] = 0;
            v[i] = false;
            dis[i] = IMAX;
            G[i].clear();
        }
        ffor(i, 1, m)
        {
            int x, y, z;
            scanf("%d%d%d", &x, &y, &z);
            if (z >= 0)
            {
                G[x].push_back(unit(y, z));
                G[y].push_back(unit(x, z));
            }
            else G[x].push_back(unit(y, z));
        }
        if (spfa(1, n))
            cout << "YE5" << endl;
        else cout << "N0" << endl;
    }
}

 

POJ2387 – Til the Cows Come Home(最短路/SPFA)

刚学了SPFA,利用队列来松弛边,虽然没DJ稳定,但是可以用来判断负环和负边权,记下来emmm

AC代码:

#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<string>
#include<vector>
#include<cstdio>
#include<stack>
#include<cmath>
#include<ctime>
#include<queue>
#include<deque>
#include<list>
#include<map>
#define ffor(i, a, b) for(int i = a; i <= b; i++)
#define rfor(i, a, b) for(int i = a; i >= b; i--)
#define mes(a,b) memset(a, b, sizeof(a))
#define cos(x) cos(x*PI/180.0)
#define sin(x) sin(x*PI/180.0)
#define stop system("pause")
#define see(s,x) cout<<(s)<<'='<<(x)<<endl
#define IMAX 0x7fffffff
#define PI 3.141592654
#define INF 0x3f3f3f3f
#define eps 1e-6
#define lowbit(x) (x&(-x))
typedef long long ll;
const ll mod = (ll)1e9 + 7;
ll max(ll a, ll b) { return(a > b) ? a : b; }
ll min(ll a, ll b) { return(a < b) ? a : b; }
using namespace std;

struct unit
{
    int to;
    int w;
    unit() {};
    unit(int a, int b) :to(a), w(b) {};
};

vector<unit> G[1005];
int dis[1005];
bool v[1005];

void spfa(int s,int n)
{
    ffor(i, 1, n)
    {
        v[i] = false;
        dis[i] = IMAX;
    }
    dis[s] = 00;
    queue<int> q;
    q.push(s);
    while (!q.empty())
    {
        int f = q.front();
        q.pop();
        v[f] = false;
        for (vector<unit>::iterator it = G[f].begin(); it != G[f].end(); it++)
        {
            unit u = *it;
            if (dis[f] + u.w < dis[u.to])
            {
                dis[u.to] = dis[f] + u.w;
                if (!v[u.to])
                {
                    q.push(u.to);
                    v[u.to] = true;
                }
            }
        }
    }
}

int main()
{
    int n, m;
    cin >> m >> n;
    ffor(i, 1, m)
    {
        int x, y, z;
        scanf("%d%d%d", &x, &y, &z);
        G[x].push_back(unit(y, z));
        G[y].push_back(unit(x, z));
    }
    spfa(1, n);
    cout << dis[n] << endl;
}