zoukankan      html  css  js  c++  java
  • 8.9 Round 1

    今天是这几天考试中唯一一次发挥正常一点儿的...

    T1:https://www.luogu.org/problem/T93119

    这么小的数据,O(n^3)暴力就行

    而我非常愚蠢加个二分,一样可以过

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<climits>
    #include<map>
    #include<queue>
    #include<cmath>
    using namespace std;
    #define O(x) cout << #x << " " << x << endl;
    #define B cout << "breakpoint" << endl;
    #define clr(a) memset(a,0,sizeof(a));
    inline int read()
    {
        int ans = 0,op = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9')
        {
            if(ch == '-') op = -1;
            ch = getchar();
        }
        while(ch >= '0' && ch <= '9')
        {
            (ans *= 10) += ch - '0';
            ch = getchar();
        }
        return ans * op;
    }
    const int maxn = 305;
    int a1[maxn],a2[maxn];
    int n,k;
    char s[maxn];
    inline bool check(int d)
    {
        for(int i = 1;i + d - 1<= n;i++)
            for(int j = 1;j + d - 1 <= n;j++)
                {
                    int cnt = 0;
                    for(int t = 0;t < d;t++)
                        if(a1[i + t] != a2[j + t]) cnt++;
                    if(cnt <= k) return 1;
                }
        return 0;
    }
    int main()
    {
        freopen("master.in","r",stdin);
        freopen("master.out","w",stdout);
        n = read(),k = read();
        scanf("%s",s); for(int i = 1;i <= n;i++) a1[i] = (int)s[i - 1] - 'a' + 1;
        scanf("%s",s); for(int i = 1;i <= n;i++) a2[i] = (int)s[i - 1] - 'a' + 1;
        int l = 0,r = n;
        while(l < r)
        {
            int mid = (l + r + 1) >> 1;
            if(check(mid)) l = mid;
            else r = mid - 1;
        }
        printf("%d",l);
    }
    /*
    7 2
    aabbaba
    bababbc
    */
    View Code

    T2:https://www.luogu.org/problem/T93120

    考场上自信以为自己写的正解,没想到复杂度算错...

    下次以为切题的时候,一定要好好算复杂度

    70pts:f[u][s]:位于点u,还剩s条边可走

    枚举起点s,容易处理环的情况

    O(N^3)

    正解:不考虑环,对于一条边u->v,它对答案的贡献是(d[u] - 1) *(d[v] - 1);

    考虑去掉三元环,令s1为u能到达的点集,s2为v能到达的点集,这样对于s1与s2的并集,他们都可以成为三元环

    于是统计并集中的点数,减去答案即可

    用bitset记录点集,O(n^3 / 32)

    bitset怎么用么...:https://www.cnblogs.com/zwfymqz/archive/2018/04/02/8696631.html

    /*#include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<climits>
    #include<map>
    #include<queue>
    #include<cmath>
    #pragma GCC optimize(3)
    #pragma GCC optimize("Ofast")
    using namespace std;
    #define O(x) cout << #x << " " << x << endl;
    #define B cout << "breakpoint" << endl;
    #define clr(a) memset(a,0,sizeof(a));
    typedef long long ll;
    inline int read()
    {
        int ans = 0,op = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9')
        {
            if(ch == '-') op = -1;
            ch = getchar();
        }
        while(ch >= '0' && ch <= '9')
        {
            (ans *= 10) += ch - '0';
            ch = getchar();
        }
        return ans * op;
    }
    const int maxn = 1505;
    struct edge
    {
        int to,next;
    }e[maxn * maxn];
    int fir[maxn],alloc;
    void adde(int u,int v)
    {
        e[++alloc].next = fir[u]; fir[u] = alloc; e[alloc].to = v;
        swap(u,v);
    }
    int s;
    ll f[maxn][4];//f[u][step] : 在u,剩step条边可走的方案 
    ll dfs(int u,int pre,int step)//在u,前一个点为pre,剩step条边可走 的方案数 
    {
        if(f[u][step]) return f[u][step];
        if(step == 0) return 1ll;
        for(int i = fir[u];i;i = e[i].next)
        {
            int v = e[i].to;
            if(v == s) continue;
            f[u][step] += dfs(v,u,step - 1); 
        }
        if(step == 1) f[u][step]--;
        return f[u][step];
    }
    int main()
    {
        freopen("tour.in","r",stdin);
        freopen("tour.out","w",stdout);
        int n = read();
        for(int i = 1;i <= n;i++)
            for(int j = 1;j <= n;j++)
                {
                    int x;
                    scanf("%1d",&x);
                    if(x) adde(i,j);
                }
        ll ans = 0;
        for(int i = 1;i <= n;i++)
        {
            clr(f); s = i;
            ans += dfs(s,0,3);
        }
        printf("%lld",ans);
    }*/
    /*
    4
    0101
    1010
    0101
    1010
    */
    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<climits>
    #include<map>
    #include<queue>
    #include<cmath>
    #include<bitset>
    #pragma GCC optimize(3)
    #pragma GCC optimize("Ofast")
    using namespace std;
    #define O(x) cout << #x << " " << x << endl;
    #define B cout << "breakpoint" << endl;
    #define clr(a) memset(a,0,sizeof(a));
    typedef long long ll;
    inline int read()
    {
        int ans = 0,op = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9')
        {
            if(ch == '-') op = -1;
            ch = getchar();
        }
        while(ch >= '0' && ch <= '9')
        {
            (ans *= 10) += ch - '0';
            ch = getchar();
        }
        return ans * op;
    }
    typedef long long ll;
    const int maxn = 1505;
    int d[maxn];
    bitset<1505> in[maxn];
    int main()
    {
        freopen("tour.in","r",stdin);
        freopen("tour.out","w",stdout);
        int n = read();
        for(int i = 1;i <= n;i++)
            for(int j = 1;j <= n;j++)
            {
                int x; scanf("%1d",&x);
                if(x) d[i]++,in[i][j] = 1;
            }
        ll ans = 0;
        for(int i = 1;i <= n;i++)
            for(int j = 1;j < i;j++)
            {
                if(!in[i][j]) continue;
                ll x = 1ll * (in[i] & in[j]).count();
                ans += (d[i] - 1) * (d[j] - 1) - x;
            }
        printf("%lld",ans << 1);
    }
    View Code

    T3:https://www.luogu.org/problem/T93121

    考场上Trie树乱搞,至今不知道为什么是错的...

    正解是优化建边

    对于每一个i,把val[i]拆出来,i->val[i]连一条边权为1的边,然后val[i]向val[i]去掉一个1的权点连边,边权为0

    先bfs,对于队首u,先走u的边权为1的边,再dfs边权为0的边

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<climits>
    #include<map>
    #include<queue>
    #include<cmath>
    using namespace std;
    #define O(x) cout << #x << " " << x << endl;
    #define B cout << "breakpoint" << endl;
    #define clr(a) memset(a,0,sizeof(a));
    #define pii pair<int,int>
    #define mp make_pair
    #define fi first
    #define se second
    inline int read()
    {
        int ans = 0,op = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9')
        {
            if(ch == '-') op = -1;
            ch = getchar();
        }
        while(ch >= '0' && ch <= '9')
        {
            (ans *= 10) += ch - '0';
            ch = getchar();
        }
        return ans * op;
    }
    const int maxn = 2e6 + 5;
    struct edge
    {
        int to,next,cost;
    }e[maxn << 1];
    int fir1[maxn],alloc,fir2[maxn];
    void adde(int u,int v,int op)
    {
        if(op == 1) e[++alloc].next = fir1[u], fir1[u] = alloc, e[alloc].to = v;
        else e[++alloc].next = fir2[u],fir2[u] = alloc,e[alloc].to = v;
    }
    const int M = 1 << 20;
    int dis[maxn];
    queue<int> q;
    int n,m;
    void dfs(int u,int d)
    {
        if(dis[u] >= 0) return;
        dis[u] = d;
        q.push(u);
        for(int i = fir2[u];i;i = e[i].next) dfs(e[i].to,d);
        if(u > M) return;
        for(int i = 0;i < 20;i++) if(u >> i & 1) dfs(u ^ (1 << i),d);
    }
    void bfs()
    {
        memset(dis,-1,sizeof(dis));
        dis[M + 1] = 0;
        q.push(M + 1);
        dfs(M + 1,0);
        while(q.size())
        {
            int u = q.front(); q.pop();
            for(int i = fir1[u];i;i = e[i].next) dfs(e[i].to,dis[u] + 1); 
        }
        for(int i = 1;i <= n;i++)
            printf("%d
    ",dis[M + i]);
    }
    int main()
    {
        freopen("walk.in","r",stdin);
        freopen("walk.out","w",stdout);
        n = read(),m = read();
        for(int i = 1;i <= n;i++) 
        {
            int x = read();
            adde(M + i,x,1);
            adde(x,M + i,2);
        }
        for(int i = 1;i <= m;i++)
        {
            int u = read(),v = read();
            adde(u + M,v + M,1);
        }
        bfs();
    }
    View Code
  • 相关阅读:
    ExtAspNet下通过文档路径实现文档的下载
    ExtjS学习--------Ext.define定义类
    【C语言天天练(二三)】errno变量
    Linux 内核kobject 层次, kset, 和子系统
    Linux 内核释放函数和 kobject 类型
    Linux 内核引用计数的操作
    Linux 内核 kobject 初始化
    Linux 内核 嵌入的 kobjects
    Kobjects, Ksets 和 Subsystems
    Kobjects, Ksets 和 Subsystems
  • 原文地址:https://www.cnblogs.com/LM-LBG/p/11329507.html
Copyright © 2011-2022 走看看