Loi隊內胡策 round 1 - 5

之前進行了一星期的胡策,一直坑着沒寫233,今天決定補上。
由於不可描述的原因,進行了爲期一週的隊內胡策(互相傷害),每次出題人不同,題目方向不同,但所有算法確實是在noip範圍內,都是套路啊,被學弟學妹們虐的死去活來233。

round 1


round 1 由swc , imcy , xczhw三位老年選手出題╮(╯▽╰)╭。題目大都可以找到原題233.

T1

swc的T1
swc正在找題的時候,imcy突然發現這個題只要換下輸入就非常勁233,於是就有了t1,有了這個樣例
這裏寫圖片描述
實際效果非常有視覺衝擊力233.
所以說題解就是求個連通塊。
std如下

#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
int map[500][500];
struct doubi{
    int x,y;
};
int n,m;
queue<doubi> q;
int x_x[13]={0,0,0,1,-1,1,1,-1,-1,0,0,2,-2};
int y_y[13]={0,1,-1,0,0,1,-1,1,-1,2,-2,0,0};
bool can(int x,int y)
{
    if(x>=1&&x<=n&&y>=1&&y<=m)
        return true;
    return false;
}
void bfs(int i,int j)
{
    doubi s;
    s.x=i,s.y=j;
    q.push(s);
    while(!q.empty())
    {
        doubi u=q.front();
        q.pop();
        int x=u.x,y=u.y;
        for(int i=1;i<=12;i++){
            int X=x+x_x[i];
            int Y=y+y_y[i];
            if(can(X,Y)&&map[X][Y]){
                doubi nxt;
                nxt.x=X,nxt.y=Y;
                q.push(nxt);
                map[X][Y]=0;
            }
        }
    }
}
int main()
{
    freopen("chinese.in","r",stdin);
    freopen("chinese.out","w",stdout);
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                string x;
                cin>>x;
                if(x=="井號"){
                    map[i][j]=1;
                }
            }
        }
        int ans=0;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                if(map[i][j]){
                    bfs(i,j);
                    ans++;
                }
            }
        }
        cout<<ans<<endl;
    fclose(stdin);
    fclose(stdout);
    return 0;
}

T2


imcy的T2
一個USACO的題目,當時做的時候一眼建圖,然後打了個最短路233,發現樣例過不了,仔細閱讀題目後,神tm最短路,把每個點都連起來再加上幾個井,明明是最小生成樹233,題目沿用了luogu.org上的翻譯.
std如下

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int size = 200010;
int n;
int num[size];
struct dc
{
    int f,t,d;
}l[size];
int tot = 1;
void build(int f,int t,int d)
{
    l[tot].f = f;
    l[tot].t = t;
    l[tot].d = d;
    tot ++;
}
int f[size];
int find(int x)
{
    if(f[x] == x)
        return x;
    return f[x] = find(f[x]);
}
bool cmp(dc a,dc b)
{
    return a.d < b.d;
}
void init()
{
    tot = 1;
    memset(num,0,sizeof(num));
    memset(l,0,sizeof(l));
    memset(f,0,sizeof(f));
}
int main()
{
    freopen("farmer_m.in","r",stdin);
    freopen("farmer_m.out","w",stdout);
    scanf("%d",&n);
    for(int i = 1 ; i <= n ; i ++)
        scanf("%d",&num[i]) , f[i] = i;
    for(int i = 1 ; i <= n ; i ++)
        for(int j = 1 ; j <= n ; j ++)
        {
            int d;
            scanf("%d",&d);
            build(i,j,d);
        }
    for(int i = 1 ; i <= n ; i ++)
        build(0,i,num[i]);
    sort(l+1,l+tot,cmp);
    int ans = 0;
    for(int i = 1 ; i < tot ; i ++)
    {
        int ff = l[i].f , ft = l[i].t;
        if(find(ff) != find(ft))
        {
            f[find(ff)] = find(ft);
            ans += l[i].d;
        }
    }
    printf("%d\n",ans);
    fclose(stdin);
    fclose(stdout);
    return 0;
}

T3


xczhw的超長題面
xczhw的賊長題面
題目是faebdc神犇曾給提供的模擬賽的t3,題面被魔改的非常辣眼233.一個樹上LCA亂搞的好題,具體見代碼
std如下

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define KILL puts("haha");
using namespace std;
typedef long long ll;
const ll MAXN = 100000 + 5;
const ll MAXM = 100000 + 5;
const ll P = 1e9 + 7;
struct edge
{
    ll f,t,v;
}l[MAXM << 1];
ll first[MAXN],next[MAXM << 1],tot;
ll n;
void init()
{
    memset(first,0xfff,sizeof(first));
    tot = 0;
    return;
}
void build(ll f,ll t,ll v)
{
    l[++tot] = (edge){f,t,v};
    next[tot] = first[f];
    first[f] = tot;
    return;
}
ll fa[MAXN][35],deep[MAXN];
void get_fa()
{
    for(int j = 1;j <= 30;j ++)
        for(int i = 1;i <= n;i ++)
            fa[i][j] = fa[fa[i][j - 1]][j - 1];
}
ll lca(ll x,ll y)
{
    if(deep[x] < deep[y])
        swap(x,y);
    for(int j = 30;j >= 0;j --)
        if(deep[fa[x][j]] >= deep[y])
            x = fa[x][j];
    if(x == y)
        return x;
    for(int j = 30;j >= 0;j --)
        if(fa[x][j] != fa[y][j])
            x = fa[x][j],y = fa[y][j];
    return fa[x][0];
}
ll sz[MAXN];
void dfs(ll x,ll f)
{
    fa[x][0] = f;
    sz[x] = 1;
    deep[x] = deep[f] + 1;
    for(int i = first[x];~i;i = next[i])
        if(l[i].t != f)
        {
            dfs(l[i].t,x);
            sz[x] += sz[l[i].t];
        }
    return;
}
ll root[MAXN];
ll ci(ll x,ll y)
{
    if(deep[x] < deep[y])
        swap(x,y);
    return sz[x] * (n - sz[x]);
}
void dfs(ll x)
{
    root[x] = root[fa[x][0]] + ci(fa[x][0],x);
    for(int i = first[x];~i;i = next[i])
        if(l[i].t != fa[x][0])
            dfs(l[i].t);
    return;
}
ll ans = 0;
void solve()
{
    for(int i = 1;i <= tot;i += 2)
        ans += (ci(l[i].f,l[i].t) % P * l[i].v % P) % P,ans %= P;
    ans %= P;
    return;
}
ll m;
ll f,t,v;
ll read()
{
    ll x = 0 , f = 1;
    char in = getchar();
    while(in < '0' || in > '9')
    {
        if(in == '-')
            f = -1;
        in = getchar();
    }
    while(in >= '0' && in <= '9')
    {
        x = (x << 3) + (x << 1) + in - '0';
        in = getchar();
    }
    return x * f;
}
int main()
{
    freopen("MaHouShaoJiuDQS.in","r",stdin);
    freopen("MaHouShaoJiuDQS.out","w",stdout);
    init();
    n = read();
    for(int i = 1;i < n;i ++)
    {
        f = read() , t = read() , v = read();
        while(v < 0)
            v += P;
        v %= P;
        build(f,t,v);
        build(t,f,v);
    }
    dfs(1,0);
    get_fa();
    dfs(1);
    solve();
    printf("%lld\n",ans);
    m = read();
    for(int i = 1;i <= m;i ++)
    {
        f = read() , t = read() , v = read();
        while(v < 0)
            v += P;
        v %= P;
        ans = ((ans % P + (root[f] % P + root[t] % P - ((root[lca(f,t)] % P) << 1) % P) % P * (v % P)) % P) % P;
        while(ans < 0)
            ans += P;
        printf("%lld\n",ans % P);
        ans %= P;
    }
    fclose(stdin);
    fclose(stdout);
    return 0;
}

這次胡策學弟(妹)們表現的還不錯,該A的A,該暴力的暴力233.


round 2


round 2 由 black,francis,knight,qer出題。

T1

black的題面
看完題一臉矇蔽233,開始手推公式,半小時後放棄,一個半小時後打出表來發現正解233,知道正解後纔想起來之前好像聽哪位學長說過fib的公比爲(√5 - 1)/2,於是A掉T1,差點被套路到233。
代碼如下

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
unsigned long long f[450];
int main()
{
    freopen("DQSjangke.in","r",stdin);
    freopen("DQSjangke.out","w",stdout);
    unsigned long long n;
    int m;
    cin>>n;
    f[0] = 1;
    f[1] = 1;
    for(int i = 2 ;  ; i ++)
    {
        f[i] = f[i-1] + f[i-2];
        if(f[i] > n || f[i] < 0)
        {
            m = i;
            break;
        }
    }
    m --;
    cout<<f[m-1]<<"/"<<f[m];
    fclose(stdin);
    fclose(stdout);
    return 0;
}

T2

francis的題面
看完題還是一臉矇蔽,T1已經用了一半時間,這個題也沒多想,感覺貪心好像可以,每次拿一個儘量大且合法的分離器裝上,然後簡單想了下證明,複雜度O(k),就直接T3了,考完才發現k是10^9,只拿了部分分+手動讀入騙來的分,加個二分就可以過了,還可以O(1)求解,然而我不會233。
std如下

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
void read(ll &n)
{
    n = 0;
    char a = getchar();
    while(a<'0'||a>'9')
        a = getchar();
    while(a>='0'&& a<='9')
    {
        n*=10;
        n+=a-'0';
        a = getchar();
    }
}
int main()
{
    freopen("project.in", "r", stdin);
    freopen("project.out", "w", stdout);
    ll n, k, d, t;
    read(n);read(k);
    d=k*k - k - 2*n + 2;
    if(d < 0)
        puts("-1");
    else
    {
        t = (int)(sqrt(d));
        printf("%lld", k-1-t+(t*t+t>d));
    }
}

knight的題面
加了一點點特技的揹包,然而當時沒時間了比較慌,沒想到n^2算法,於是大力暴力n^3,神tmA了233.
代碼如下

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
ll read()
{
    int x = 0 , f = 1;
    char in = getchar();
    while(in < '0' || in > '9')
    {
        if(in == '-')
            f = -1;
        in = getchar();
    }
    while(in >= '0' && in <= '9')
    {
        x = x * 10 + in - '0';
        in = getchar();
    }
    return x * f;
}
ll f[4010];
int m,n;
ll w[2010],a[2010],b[2010];
int main()
{
    freopen("candy.in","r",stdin);
    freopen("candy.out","w",stdout);
    scanf("%d%d",&m,&n);
    for(int i = 1 ; i <= n ; i ++)
        w[i] = read() , a[i] = read() , b[i] = read();
    for(int i = 1 ; i <= n ; i ++)
        for(int j = m ; j >= w[i] ; j --)
            for(int k = 1 ; j - k * w[i] >= 0 ; k ++)
                f[j] = max(f[j],f[j-k*w[i]]+k*(a[i]+b[i])-(k-1)*b[i]);
    printf("%lld\n",f[m]);
    fclose(stdin);
    fclose(stdout);
    return 0;
}
/*
100 2
10 2 1
20 1 50

68
*/

T4

qer的題面
題解強行noip233,就是把數位dp的過程搞了下,數位dp不可免233,非noip內容這裏就不bb了。
std如下

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
typedef long long LL;

const int MAXN = 65;
LL c[MAXN][MAXN];
LL bin[MAXN];

void read(LL &n)
{
    n = 0;
    char a = getchar();
    while(a<'0'||a>'9')
        a = getchar();
    while(a>='0'&& a<='9')
    {
        n*=10;
        n+=a-'0';
        a = getchar();
    }
}

void init()
{
    for(int i = 0; i < MAXN; i ++)
        c[i][0] = 1;
    for(int i = 1; i < MAXN; i ++)
        for(int j = 1; j < MAXN; j ++)
            c[i][j] = c[i-1][j] + c[i-1][j-1];
}

LL Get_bin(LL x)
{
    bin[0] = 0;
    while(x)
    {
        bin[++bin[0]] = x%2;
        x >>= 1;
    }
}

LL Get_Rn(LL x)
{
    LL sum = 0;
    Get_bin(x); // 獲得二進制數

    // 長度小於 x
    for(int i = bin[0]-1; i > 1; i --)
        for(int j = (i+1)/2; j <= i-1; j ++)
            sum += c[i-1][j];
//  sum = 0;
    // 長度等於 x // 需要的 0 恆大於 (bin[0]+1)/2
    LL zero = 0;
    for(LL i = bin[0]-1; i >= 1; i --) // 本來就有一個 1
        if(bin[i])
            for(LL j = ((bin[0]+1)/2)-1-zero; j <= i-1; j ++)
                sum += c[i-1][j];
        else zero ++;

    return sum;
}

int main()
{
    freopen("Oierdqs.in","r",stdin);
    freopen("Oierdqs.out","w",stdout);
    LL a, b;
    read(a);read(b);
    init();
//  cout << Get_Rn(b+1) << endl;
    printf("%llu", Get_Rn(b+1)-Get_Rn(a));
    return 0;
}

round 2的t1,t2都挺有意思的,不失爲一種思路,數位dp我剛接觸沒幾天,對t4不做評價,t3有點裸了,恩恩,不過學弟們的題賊帶勁。


round 3

round 3 是 jhz lcy ljx msy zzk出題,題目賊勁啊,神tmT2就到ctsc了233.

T1

jhz的題面
一個有坑的暴力題,注意下邊界沒啥問題。
代碼如下

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define ll long long
using namespace std;
ll num[511][511];
int n;
int px,py;
bool check()
{
    ll ans = 0 , temp = 0;
    for(int i = 1 ; i <= n ; i ++)
        ans += num[i][i];
    for(int i = 1 ; i <= n ; i ++)
        temp += num[i][n-i+1];
    if(ans != temp)
        return false;
    for(int i = 1 ; i <= n ; i ++)
    {
        temp = 0;
        for(int j = 1 ; j <= n ; j ++)
            temp += num[i][j];
        if(temp != ans)
            return false;
    }
    for(int i = 1 ; i <= n ; i ++)
    {
        temp = 0;
        for(int j = 1 ; j <= n ; j ++)
            temp += num[j][i];
        if(temp != ans)
            return false;
    }
    return true;
}
int main()
{
    freopen("business.in","r",stdin);
    freopen("business.out","w",stdout);
    scanf("%d",&n);
    for(int i = 1 ; i <= n ; i ++)
        for(int j = 1 ; j <= n ; j ++)
        {
            scanf("%lld",&num[i][j]);
            if(num[i][j] == 0)
                px = i , py = j;
        }

    int pos = 0;
    if(n == 1)
    {
        puts("1");
        fclose(stdin);
        fclose(stdout);
        return 0;
    }
    else if(px == 1)
        pos = 2;
    else if(px == n)
        pos = n - 1;
    else
        pos = px + 1;
    ll ans = 0;
    for(int i = 1 ; i <= n ; i ++)
        ans += num[pos][i];
    for(int i = 1 ; i <= n ; i ++)
        ans -= num[px][i];
    num[px][py] = ans;
    if(check())
        printf("%lld\n",ans);
    else
        puts("-1");
    fclose(stdin);
    fclose(stdout);
    return 0;
}

T2

誰知道誰的題面
到底是誰的題面
對字符串的題一直不敏感233,做到這一臉懵逼,思考過後決定打暴力233.
考完後知道原題是ctsc的,嚇尿了233,正解是hash。
std如下

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
typedef unsigned long long ULL; 
const int p = 2333;

char s[30010][550];
ULL hash[50000], py[500], ls[50000];

int main()
{
    freopen("gbwl.in", "r", stdin);
    freopen("gbwl.out", "w", stdout);
    int len, n, si;
    scanf("%d%d%d", &n, &len, &si);
    py[0] = 1;
    for(int i = 1; i <= 210; i++)
        py[i] = py[i - 1] * p;
    for(int i = 1; i <= n; i++)
        scanf("%s", s[i] + 1);
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= len; j++)
            hash[i] = hash[i] * p + s[i][j];
    int pr = 1, ans = 0;
    for(int i = 1; i <= len; i++)
    {
        for(int j = 1; j <= n; j++)
            ls[j] = hash[j] - s[j][i] * py[len - i];
        sort(ls + 1, ls + n + 1);
        for(int j = 2; j <= n; j++)
        {
            if(ls[j] == ls[j - 1])
            {
                ans += pr;
                pr ++;
            }
            else
                pr = 1;
        }
    }
    printf("%d", ans);
    return 0;

T3

神tmnoip
233
嗨呀好氣呀
去年noiptg組day2t3原題,然而我現在還是不會233,直接上分段函數,palapala打了200+行,評測的時候發現好像打次了!?跪慘。
std如下

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int SZ = 300010;

struct Plan
{
    int u, v, lca, dis;
}p[SZ];
struct Edge
{
    int f, t, d;
}es[SZ << 1];
int first[SZ << 1], nxt[SZ << 1], tot = 1, cnt; 
int n, m, jump[SZ][30], dis[SZ], in[SZ];
int recover[SZ], cost[SZ], depth[SZ];   
int u, v, w, TOT = 0, l, r, mid;
bool vis[SZ];

int read()
{
    int f = 1, num = 0;
    char c = getchar();
    while(c < '0' || '9' < c)
    {
        if(c == '-') f = -1; 
        c = getchar();
    }
    while('0' <= c && c <= '9')
    {
        num = num * 10 + (c - '0');
        c = getchar();
    }
    return num *= f;
}

inline void build(int ff, int tt, int dd)
{
    es[++tot] = (Edge){ff, tt, dd};
    nxt[tot] = first[ff];
    first[ff] = tot;
    es[++tot] = (Edge){tt, ff, dd};
    nxt[tot] = first[tt];
    first[tt] = tot;
}

inline void dfs(int u)
{
    for(int i = 1; i <= 17; ++i)
        jump[u][i] = jump[jump[u][i - 1]][i - 1];
    vis[u] = 1;
    in[++cnt] = u;
    for(int i = first[u]; i; i = nxt[i])
    {
        int v = es[i].t;
        if(vis[v]) continue;
        jump[v][0] = u;
        depth[v] = depth[u] + 1;
        dis[v] = dis[u] + es[i].d;
        cost[v] = es[i].d;
        dfs(v); 
    }
}

int get_lca(int uu, int vv)
{
    if(depth[uu] < depth[vv]) swap(uu, vv);
    int t = depth[uu] - depth[vv];
    for(int i = 0; i <= 17; ++i)
        if((t >> i) & 1) uu = jump[uu][i];
    for(int i = 17; i >= 0; --i)
        if(jump[uu][i] != jump[vv][i])
            uu = jump[uu][i], vv = jump[vv][i];
    if(uu == vv) return uu;
    return jump[uu][0];
}

bool check(int mid)
{
    for(int i = 1; i <= n; ++i) recover[i] = 0;
    int tot = 0, maxn = 0;
    for(int i = 1; i <= m; ++i)
        if(p[i].dis > mid)
        {
            ++tot;
            maxn = max(p[i].dis, maxn);
            ++recover[p[i].u]; ++recover[p[i].v]; recover[p[i].lca]-=2;
        }
        //else break;
    if(!tot) return true;
    for(int i = cnt; i > 1; --i) recover[jump[in[i]][0]] += recover[in[i]];
    for(int i = 2; i <= n; ++i)
        if(maxn - cost[i] <= mid && recover[i] == tot) return true;
    return false;
}

int main()
{
    int __size__ = 1024 << 15;
    char * __p__ = (char *) malloc(__size__) + __size__;
    __asm__("movl %0, %%esp\n" :: "r"(__p__));
    freopen("foolish.in", "r", stdin);
    freopen("foolish.out", "w", stdout);
    n = read(); m = read();

    for(int i = 1; i < n; ++i)
    {
        u = read(), v = read(), w = read();
        build(u, v, w); TOT += w;
    }
    depth[1] = 1;
    dfs(1);
    for(int i = 1; i <= m; ++i)
    {
        p[i].u = read(); p[i].v = read();
        //cout<<depth[p[i].u]<<" "<<depth[p[i].v]<<endl;
        p[i].lca = get_lca(p[i].u, p[i].v);
        p[i].dis = dis[p[i].u] + dis[p[i].v] - (dis[p[i].lca] << 1);
        //cout<<p[i].lca<<endl;
    }
    l = 0, r = TOT;
    while(l <= r)
    {
        mid = (l + r) >> 1;
        if(check(mid)) r = mid - 1;
        else l = mid + 1;
    }
    printf("%d", l);
    fclose(stdin);
    fclose(stdout);
    return 0;
}

胡策以來跪的最慘的一次考試233,基本都是暴力分。


round 4

出題 by 天線 DL fluency a 帝江

考試時的cy:T1裸中餘定,然而我不會,上暴力233,T2一模擬!?,瞎搞一搞,好像會有精度問題,T3sx題直接過,T4什麼玩意,好像線段樹能搞?拿線段樹搞一搞。於是就有了T1暴力,T2翻車,T3AC,T4暴力的cy ╮(╯▽╰)╭。

T1

天線的題面
中國剩餘定理Orz,不過還是暴力大法好233.
std如下

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
const int MAXN=1000+10;
int a[MAXN],b[MAXN];

LL exgcd(LL a,LL b,LL &x,LL &y)//擴展歐幾里得 
{
    if(b==0)
    {
        x=1;
        y=0;
        return a;
    }
    else
    {
        LL p=exgcd(b,a%b,x,y);
        LL t=x;
        x=y;
        y=t-a/b*x;
        return p;
    }

}

/*x%a[i]==b[i]*/
LL China(int n)//中國剩餘定理 
{
    LL M=1,d,x=0,y;
    for(int i=1;i<=n;i++)
        M*=(LL)a[i];
    for(int i=1;i<=n;i++)
    {
        LL w=M/(LL)a[i];
        exgcd(w,a[i],d,y);
        x=(x+d*w*b[i])%M;  
    }
    return (x+M)%M;
}

int main()
{
    freopen("Question.in","r",stdin);
    freopen("Question.ans","w",stdout);
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d%d",&a[i],&b[i]);
    printf("%lld\n",China(n));
    return 0;
}

T2

DL的題面
確實就是一個模擬,不過我好像搞錯了什麼233,直接上代碼
std如下

#include<cstdio>
#include<cmath>
#include<algorithm>
#define inf 598460606
#define LL long long
using namespace std;
int n,m,per=1;
int lt,ld,nt=1;
char ch[5];
double t[210000],d[210000],x,nowt;
int main()
{
    freopen("dig.in","r",stdin);
    freopen("dig.out","w",stdout);
    scanf("%d%d",&n,&m);
    for (int i=1;i<=n;i++)
     {
        scanf("%s%lf",ch,&x);
        if (ch[0]=='T')t[++lt]=x;
        else d[++ld]=x;
     }
    d[++ld]=0.0;
    d[++ld]=m;
    sort(d+1,d+ld+1);
    sort(t+1,t+lt+1);
    for(int i=1;i<ld;i++)
      {
        double nd=d[i];
        while (nd<d[i+1]&&nt<=lt&&nowt+(d[i+1]-nd)*per>t[nt])
        {
            nd+=(t[nt]-nowt)/per;
            per++;
            nowt=t[nt++];
        }
        nowt+=(d[i+1]-nd)*per;
        per++;
      }
    printf("%I64d\n",(long long)nowt);
}

T3

fluency的題面
出題人好像是想要考代碼細節處理?好多人都在這題上翻車了233,注意下並不只是判斷最短路上是否存在負環就好吧。
代碼如下

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define ll long long
using namespace std;
const int size = 2001000;
int read()
{
    int x = 0 , f = 1;
    char in = getchar();
    while(in < '0' || in > '9')
    {
        if(in == '-')
            f = -1;
        in = getchar();
    }
    while(in >= '0' && in <= '9')
    {
        x = x * 10 + in - '0';
        in = getchar();
    }
    return x * f;
}
int head[size],nxt[size];
ll dist[size];
int tot = 1;
struct gtnd
{
    int t;
    ll d;
}l[size];
int n,m;
void build(int f,int t,int d)
{
    l[tot].t = t;
    l[tot].d = d;
    nxt[tot] = head[f];
    head[f] = tot ++;
}
queue < int > q;
bool use[size];
bool vis[size];
int tim[size];

void dfs(int u)
{
    vis[u] = 1;
    for(int i = head[u] ; i ; i = nxt[i])
        if(!vis[l[i].t])
            dfs(l[i].t);
}
void init()
{
    while(!q.empty())
        q.pop();
    for(int i = 1 ; i <= n ; i ++)
        dist[i] = 214748364111ll;
    for(int i = 1 ; i <= n ; i ++)
        tim[i] = 0;
}
bool spfa(int s)
{
    init();
    dist[s] = 0;
    use[s] = 1;
    q.push(s);
    while(!q.empty())
    {
        int f = q.front();
        q.pop();
        use[f] = 0;
        for(int i = head[f] ; i ; i = nxt[i])
        {
            int t = l[i].t;
            if(dist[t] > dist[f] + l[i].d)
            {
                dist[t] = dist[f] + l[i].d;
                tim[t] = tim[f] + 1;
                if(tim[t] > 2 * n)
                    return false;
                if(!use[t])
                {
                    use[t] = 1;
                    q.push(t);
                }
            }
        }
    }
    return true;
}

int main()
{
    freopen("EasySSSP.in","r",stdin);
    freopen("EasySSSP.out","w",stdout);
    n = read() , m = read();
    int s = read();
    for(int i = 1 ; i <= m ; i ++)
    {
        int f = read() , t = read() , d = read();
        build(f,t,d);
    }
    for(int i = 1 ; i <= n ; i ++)
    {
        if(!vis[i])
        {
            dfs(i);
            if(!spfa(i))
            {
                puts("-1");
                fclose(stdin);
                fclose(stdout);
                return 0;
            }
        }
    }
    spfa(s);
    for(int i = 1 ; i <= n ; i ++)
    {
        if(dist[i] == 214748364111ll)
            puts("NoPath");
        else
            printf("%lld\n",dist[i]);
    }
    fclose(stdin);
    fclose(stdout); 
    return 0;
}
/*
5 5 1
1 2 1
2 1 1
3 4 2
4 5 -2
5 3 2
*/

T4

a的題面
紅太陽的題太強啦,只會暴力呀,亂搞大失敗呀233,大體意思是分下塊然後用set維護下?
std如下

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int f[300005],num[300005];
int mn[605],ans[300005];
int n;
char opt[100005];
int S[1000005],top;
int find(int i)
{
    while(f[i]!=i)
    {
        S[++top]=i;
        i=f[i];
    }
    while(top)
    {
        f[S[top]]=i;
        top--;
    }
    return i;
}
int cnt[300005];
char s[5];
int main()
{
    freopen("Math.in","r",stdin);
    freopen("Math.out","w",stdout);
    scanf("%d",&n);
    for (int i=1;i<=300000;i++) f[i]=i+1;
    memset(mn,127,sizeof(mn));
    for (int i=1;i<=n;i++)
    {
        scanf("%s",s);
        opt[i]=s[0];
        scanf("%d",&num[i]);
        if (opt[i]=='A')
        {
            for (int j=1;j<=540;j++) mn[j]=min(mn[j],num[i]%j);
            f[num[i]]=num[i];cnt[num[i]]++;
        }
        else if (num[i]<=540) ans[i]=mn[num[i]];
    }
    for (int i=n;i;i--)
    {
        if (opt[i]=='A')
        {
            cnt[num[i]]--;
            if(cnt[num[i]]==0)
                f[num[i]]=f[num[i]+1];
        }
        else if(num[i]>540)
        {
            ans[i]=find(1)%num[i];
            for (int j=num[i];j<=300000;j+=num[i])
            {
                int x=find(j);
                if (x) ans[i]=min(ans[i],x%num[i]);
            }
        }
    }
    for (int i=1;i<=n;i++) 
        if (opt[i]=='B') printf("%d\n",ans[i]);
    return 0;
}

round 5

出題 by ChlorineHikari,Yuan,Meico,Summer, (題目順序)Peacefuldoge(後期)
最後的一次胡策,題目偏向模板。
考試時的cy : T1不就模擬嗎233,T2一sx壓位搜索,wocT3K短路然而我沒學過A*,wocT4一樹形DP然而我還是沒學過╮(╯▽╰)╭。

T1

Chlorine的題面
還是Chlorine的題面
模擬搞一搞,據說是cf上的原題。
std如下

//Codeforces Round #375 (Div. 2) B
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
const int maxn=20000;
char hah[maxn];
int l[maxn];
int r[maxn];
int n;
int ans2=0;
void haha(int ll,int rr)
{
    for(int i=ll+1;i<rr;)
    {
        if(hah[i]=='_')
        i++;
        else
        {
            ans2++;
            while(hah[i]!='_'&&i<rr)
            {
                i++;
            }
        }
    }
}
int main()
{
    freopen("letter.in","r",stdin);
    freopen("letter.osu","w",stdout);
    int ans1=0;
    scanf("%d",&n);
    int lc=0;
    int rc=0;
    for(int i=1;i<=n;i++)
    {
        cin>>hah[i];
        if(hah[i]=='(')
        {
            l[++lc]=i;
        }
        if(hah[i]==')')
        {
            r[++rc]=i;
        }
    }
    for(int i=1;i<=n;)
    {
        if(hah[i]=='_')
        {
            i++;
        }
        else if(hah[i]=='(')
        {
            while(i<=n)
            {
                i++;
                if(hah[i]==')')
                break;
            }
        }
        else 
        {
            if(hah[i]==')')
            i++;
            int cnt=0;
            while(hah[i]!='_'&&hah[i]!='('&&i<=n)
            {
                i++;
                cnt++;
            }
            ans1=max(ans1,cnt);
        }
    }
    for(int i=1;i<=lc;i++)
    {
        haha(l[i],r[i]);
    }

    cout<<ans1<<" ";
    printf("%d",ans2);
    return 0;
}

T2

Yuan的題面
還是Yuan的題面
還tm是Yuan的題面
經典的狀壓搜索問題,沒啥好注意的。
代碼如下

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int sz = 1 << 11;
const int size = 214;
struct gtnd
{
    int now;
    int step;
};
int repair[size];
int destory[size];
int n,m;
queue < gtnd > q;
bool check(int x)
{
    for(int i = 1 ; i <= n ; i ++)
        if(!((x>>i) & (1)))
            return false;
    return true;
}
bool use[1000010];
/*
void print(int x)
{
    for(int i = 1 ; i <= n ; i ++)
        printf("%d ",(x >> i) & (1));
    puts("");
}
*/
int bfs()
{
    gtnd s;
    s.now = 0;
    s.step = 0;
    use[s.now] = 1;
    q.push(s);
    while(!q.empty())
    {
        gtnd f = q.front();
        q.pop();
        if(check(f.now))
            return f.step;
        for(int i = 1 ; i <= m ; i ++)
        {
            gtnd nxt;
            nxt.now = f.now;
            nxt.now |= repair[i];
            nxt.now &= (~destory[i]);
            if(use[nxt.now] == 0)
            {
                use[nxt.now] = 1;
                nxt.step = f.step + 1;
                q.push(nxt);
            }
        }
    }
    return -1;
}
int main()
{
    freopen("glgjssy.In","r",stdin);
    freopen("glgjssy.0ut","w",stdout);
    scanf("%d%d",&n,&m);
    for(int i = 1 ; i <= m ; i ++)
    {
        for(int j = 1 ; j <= n ; j ++)
        {
            int ins;
            scanf("%d",&ins);
            if(ins == 1)
                repair[i] |= 1 << j;
            else if(ins == -1)
                destory[i] |= 1 << j;
        }
    }
    int ans = bfs();
    if(ans == -1)
        puts("GG");
    else
        printf("%d\n",ans);
    fclose(stdin);
    fclose(stdout);
    return 0;
}
/*
3 2
1 0 1
-1 1 0


3 3
1 -1 -1
-1 1 -1
-1 -1 1

3 3
1 -1 0
0 1 -1
0 0 1

1 0 1 / 0 0 0
0 1 0 / 1 0 0
*/

T3

Meico的題面
還是Meico的題面
還tm是Meico的題面
由於我對dij還A*都不感冒,考試的時候就打了個spfa求次短路糊弄了下233。
std如下

//POJ 2449 k短路 
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
const int inf=0x7fffffff;
const int maxn=100000+500;
struct Edge
{
    int to;
    int d;
    int next;
}edge[maxn],edge1[maxn];
int head[maxn],head1[maxn],h[maxn];
int n,m,ss,tt,k;
struct heap
{
    int p;
    int dis;
    int h;
    bool operator <(const heap &hah)const 
    {
        return dis+h>hah.dis+hah.h; 
    }
};
priority_queue<heap>q;
int tott;
void add(int f,int t,int d)
{
    edge[++tott].to=t;
    edge[tott].d=d;
    edge[tott].next=head[f];
    head[f]=tott;
}
int tot1;
void add1(int f,int t,int d)
{
    edge1[++tot1].to=t;
    edge1[tot1].d=d;
    edge1[tot1].next=head1[f];
    head1[f]=tot1;
}
queue<int>q1;
bool vis[maxn];
void spfa()
{
    for(int i=1;i<=n;i++)
        h[i]=inf;
    q1.push(tt);
    h[tt]=0;
    while(!q1.empty())
    {
        int x=q1.front();
        vis[x]=0;
        q1.pop();
        for(int i=head1[x];i;i=edge1[i].next)
        {
            Edge e=edge1[i];
            if(h[e.to]>h[x]+e.d)
            {
                h[e.to]=h[x]+e.d;
                if(!vis[e.to])
                {
                    vis[e.to]=1; 
                    q1.push(e.to);
                }
            }
        } 
    }
}
int ans=-1;
void DJ()
{
    int cnt=0;
    heap hah;
    hah.p=ss;
    hah.dis=0;
    hah.h=h[ss];
    q.push(hah);
    while(!q.empty())
    {
        heap pre=q.top();
        q.pop();
        int x=pre.p;
        if(x==tt)
        {
            cnt++;
            if(cnt==k)
            {
                ans=pre.dis;
                return;
            }
        }
        for(int i=head[x];i;i=edge[i].next)
        {
            Edge e=edge[i];
            q.push((heap){e.to,pre.dis+e.d,h[e.to]});
        }
    } 
}
int main()
{
    freopen("chemistry.in","r",stdin);
    freopen("chemistry.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        add(a,b,c);
        add1(b,a,c);
    }
    scanf("%d%d%d",&ss,&tt,&k);
    if(ss==tt)
    k++;
    spfa();
    DJ();
    printf("%d",ans);
    return 0;
}

T4

summer的題面
還是summer的題面
還tm是summer的題面
md題面怎麼這麼長
原題codevs選課,多叉轉二叉後跑下dp。
代碼如下

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int size = 1010;
const int sz = 200010;
int val[size];
int dist[size];
int r[size];
int len,n,m;
int head[sz],nxt[sz],l[sz];
int tot = 1;
bool use[size];
int f[size][size]; // f[i][j] 第 i 個節點 
void build(int f,int t)
{
    l[tot] = t;
    nxt[tot] = head[f];
    head[f] = tot ++;
}
struct gtnd
{
    int l, r;
}tree[size];
queue < int > q;
int read()
{
    int x = 0 , f = 1;
    char in = getchar();
    while(in < '0' || in > '9')
    {
        if(in == '-')
            f = -1;
        in = getchar();
    }
    while(in >= '0' && in <= '9')
    {
        x = (x << 3) + (x << 1) + in - '0';
        in = getchar();
    }
    return x * f;
}
int dfs(int u,int pick)
{
    if(!u)
        return 0;
    if(f[u][pick])
        return f[u][pick];
    for(int i = 0 ; i <= pick - 1 ; i ++)
        f[u][pick] = max(f[u][pick],dfs(tree[u].l,i)+val[u]+dfs(tree[u].r,pick-i-1));
    f[u][pick] = max(f[u][pick],dfs(tree[u].r,pick));
    return f[u][pick];
}
int main()
{
    freopen("dreamerpeacefuldoge.in","r",stdin);
    freopen("dreamerpeacefuldoge.out","w",stdout);
    n = read() , m = read();
    for(int i = 1 ; i <= n ; i ++)
    {
        int par = read();
        val[i] = read();
        if(tree[par].l)
            tree[i].r = tree[par].l;
        tree[par].l = i;
    }
    printf("%d\n",dfs(tree[0].l,m));
    fclose(stdin);
    fclose(stdout);
    return 0;
}

總結下,雖然我不怎麼會總結
看到學弟(妹)們越來越套路我還是很滋磁的233,大家noip加油吧233。
All Loiers rp ++;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章