• 《牛客算法周周练11》


    B:

    二分图的染色应用。

    首先,注意题目的信息。

    每个人最多有三个认识的人。

    那么,我们可以思考,当有三个人和一个人连边时。

    如果有两个人和他同色,一个人不同色。

    那么将这个人反转,就变成了,一个人和他同色,两个人不同色。

    那么可以发现,对于每一个人,翻转后可以减少同色的数量。

    可以证明,必定存在解。即存在排列,分散两堆人。

    思路:

    先对每个没有染色过的点染色,当一个点和它相邻的点的同色点>=2时,就翻转它的颜色。

    注意的是,对于一个没有染色过的点,染色过后也需要判断是否和u同色。

    因为这个v点可能在dfs下层被翻转.

    Code:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef pair<int,int> pii;
    const int N = 2e5+5;
    const int M = 1e6+5;
    const int Mod = 1e9+7;
    #define pi acos(-1)
    #define INF 1e18
    #define INM INT_MIN
    #define rg register
    #define pb(a)  push_back(a)
    #define mk(a,b) make_pair(a,b)
    #define dbg(x) cout << "now this num is " << x << endl;
    #define met0(axx) memset(axx,0,sizeof(axx));
    #define metf(axx) memset(axx,-1,sizeof(axx));
    #define sd(ax) scanf("%d",&ax)
    #define sld(ax) scanf("%lld",&ax)
    #define sldd(ax,bx) scanf("%lld %lld",&ax,&bx)
    #define sdd(ax,bx) scanf("%d %d",&ax,&bx)
    #define sddd(ax,bx,cx) scanf("%d %d %d",&ax,&bx,&cx)
    #define sfd(ax) scanf("%lf",&ax)
    #define sfdd(ax,bx) scanf("%lf %lf",&ax,&bx)
    #define pr(a) printf("%d\n",a)
    #define plr(a) printf("%lld\n",a)
    struct Node{int next,to;}e[N<<1];
    int cnt = 0,head[N],col[N];
    inline void add(int u,int v)
    {
        e[++cnt].to = v,e[cnt].next = head[u],head[u] = cnt;
    }
    void dfs(int u,int c)
    {
        col[u] = c;
        int ma = 0;
        for(int i = head[u];i;i = e[i].next)
        {
            int v = e[i].to;
            if(col[v] == 0) dfs(v,c^3);
            if(col[v] == col[u]) ma++;
        }
        if(ma >= 2) col[u] ^= 3;
    }
    void run()
    {
        int n,m;sdd(n,m);
        while(m--)
        {
            int u,v;sdd(u,v);
            add(u,v);add(v,u);
        }
        for(int i = 1;i <= n;++i) if(col[i] == 0) dfs(i,1);
        for(int i = 1;i <= n;++i) printf("%d%c",col[i],i == n ? '\n' : ' ');
    }  
    int main()
    {
        run();
        system("pause");
        return 0;
    }
    View Code

     D:

    博弈论。

    发现,对于每次变换,左上角的(1,1)始终都会变换。

    对于结果,肯定是所有都为B。

    所有对于左上角,肯定是最终变为B。

    然后R-G-B三色变换,正好是一个周期。

    所以每次经过一个周期变换,相当于没有操作。

    所以只需要判断(1,1)一开始的状态即可。

    Code:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef pair<int,int> pii;
    const int N = 2e5+5;
    const int M = 1e6+5;
    const int Mod = 1e9+7;
    #define pi acos(-1)
    #define INF 1e18
    #define INM INT_MIN
    #define rg register
    #define pb(a)  push_back(a)
    #define mk(a,b) make_pair(a,b)
    #define dbg(x) cout << "now this num is " << x << endl;
    #define met0(axx) memset(axx,0,sizeof(axx));
    #define metf(axx) memset(axx,-1,sizeof(axx));
    #define sd(ax) scanf("%d",&ax)
    #define sld(ax) scanf("%lld",&ax)
    #define sldd(ax,bx) scanf("%lld %lld",&ax,&bx)
    #define sdd(ax,bx) scanf("%d %d",&ax,&bx)
    #define sddd(ax,bx,cx) scanf("%d %d %d",&ax,&bx,&cx)
    #define sfd(ax) scanf("%lf",&ax)
    #define sfdd(ax,bx) scanf("%lf %lf",&ax,&bx)
    #define pr(a) printf("%d\n",a)
    #define plr(a) printf("%lld\n",a)
    string mp[1005];
    void run()
    {
        int t;sd(t);
        while(t--)
        {
            int n,m;sdd(n,m);
            for(int i = 0;i < n;++i) cin >> mp[i];
            if(mp[0][0] == 'G') printf("fengxunling\n");
            else if(mp[0][0] == 'R')printf("dreagonm\n");
            else printf("BLUESKY007\n");
        }
    }  
    int main()
    {
        run();
        system("pause");
        return 0;
    }
    View Code

    C:

    线段树维护一下二进制位的1即可。

    注意0应该用num-1来,记0的个数会记空的位置.

    Code:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef pair<int,int> pii;
    const int N = 1e5+5;
    const int M = 1e6+5;
    const int Mod = 1e9+7;
    #define pi acos(-1)
    #define INF 1e18
    #define INM INT_MIN
    #define rg register
    #define pb(a)  push_back(a)
    #define mk(a,b) make_pair(a,b)
    #define dbg(x) cout << "now this num is " << x << endl;
    #define met0(axx) memset(axx,0,sizeof(axx));
    #define metf(axx) memset(axx,-1,sizeof(axx));
    #define sd(ax) scanf("%d",&ax)
    #define sld(ax) scanf("%lld",&ax)
    #define sldd(ax,bx) scanf("%lld %lld",&ax,&bx)
    #define sdd(ax,bx) scanf("%d %d",&ax,&bx)
    #define sddd(ax,bx,cx) scanf("%d %d %d",&ax,&bx,&cx)
    #define sfd(ax) scanf("%lf",&ax)
    #define sfdd(ax,bx) scanf("%lf %lf",&ax,&bx)
    #define pr(a) printf("%d\n",a)
    #define plr(a) printf("%lld\n",a)
    struct Node
    {
        int L,r;
        LL sum = 0,tag = 0,cnt[25];
    }node[N<<2];
    LL a[N];
    void Pushup(int idx)
    {
        node[idx].sum = node[idx<<1].sum + node[idx<<1|1].sum;
        for(int i = 0;i < 25;++i)
        {
            node[idx].cnt[i] = node[idx<<1].cnt[i]+node[idx<<1|1].cnt[i];
        }
    }
    void Pushdown(int idx)
    {
        if(node[idx].tag != 0)
        {
            int tag = node[idx].tag;
            int num1 = (node[idx<<1].r-node[idx<<1].L+1);
            int num2 = (node[idx<<1|1].r-node[idx<<1|1].L+1);
            for(int i = 0;i < 25;++i)
            {
                int t = (tag>>i)&1;
                int a1 = node[idx<<1].cnt[i];
                int b1 = node[idx<<1|1].cnt[i];
                if(t == 1)
                {
                    node[idx<<1].sum += (1<<i)*(num1-a1);
                    node[idx<<1].sum -= (1<<i)*a1;
                    node[idx<<1|1].sum += (1<<i)*(num2-b1);
                    node[idx<<1|1].sum -= (1<<i)*b1;
                    node[idx<<1].cnt[i] = num1-a1;
                    node[idx<<1|1].cnt[i] = num2-b1;
                }
            }
            node[idx<<1].tag ^= tag;
            node[idx<<1|1].tag ^= tag;
            node[idx].tag = 0;
        }
    }
    void build(int L,int r,int idx)
    {
        node[idx].L = L,node[idx].r = r;
        if(L == r)
        {
            node[idx].sum = a[L];
            for(int i = 0;i < 25;++i)
            {
                int t = (a[L]>>i)&1;
                if(t == 1) node[idx].cnt[i]++;
            }
           // for(int i = 0;i < 25;++i) printf("i is %d cnt is %d\n",i,node[idx].cnt[i]);
            return ;
        }
        int mid = (node[idx].L+node[idx].r)>>1;
        build(L,mid,idx<<1);
        build(mid+1,r,idx<<1|1);
        Pushup(idx);
    }
    void update(int L,int r,int idx,int k)
    {
        if(node[idx].L >= L && node[idx].r <= r)
        {
            int num = (node[idx].r-node[idx].L+1);
            for(int i = 0;i < 25;++i)
            {
                int t = (k>>i)&1;
                int a1 = node[idx].cnt[i];
                if(t == 1)
                {
                    node[idx].sum += (1<<i)*(num-a1);
                    node[idx].sum -= (1<<i)*a1;
                    node[idx].cnt[i] = num-a1;
                  //  printf("i is %d a1 is %d sum is %d\n",i,a1,node[idx].sum);
                }
            }
            node[idx].tag ^= k;
        }
        else
        {
            Pushdown(idx);
            int mid = (node[idx].L+node[idx].r)>>1;
            if(mid >= L) update(L,r,idx<<1,k);
            if(mid < r) update(L,r,idx<<1|1,k);
            Pushup(idx);
        }
    }
    LL query(int L,int r,int idx)
    {
        if(node[idx].L >= L && node[idx].r <= r) return node[idx].sum;
        int mid = (node[idx].L+node[idx].r)>>1;
        LL ans = 0;
        Pushdown(idx);
        if(mid >= L) ans += query(L,r,idx<<1);
        if(mid < r) ans += query(L,r,idx<<1|1);
        return ans;
    }
    void run()
    {
        int n,m;sdd(n,m);
        for(int i = 1;i <= n;++i) sld(a[i]);
        build(1,n,1);
        while(m--)
        {
            int id;sd(id);
            if(id == 1)
            {
                int L,r;sdd(L,r);
                LL ans = query(L,r,1);
                plr(ans);
            }
            if(id == 2)
            {
                int L,r,k;sddd(L,r,k);
                update(L,r,1,k);
            }
        }
    }  
    int main()
    {
        run();
       // system("pause");
        return 0;
    }
    View Code
  • 相关阅读:
    【Python】表白代码
    有关加密技术的概述,黑客是如何破解加密数据?
    Kali Linux的发展史,专为数字取证和渗透测试而设计
    在Wi-Fi路由器中发现了新的安全漏洞
    太可怕!看看黑客是怎样利用社会工程学窃取你的密码?
    不可不知!未来警惕被黑客植入微芯片
    什么是计算机漏洞,为什么会有漏洞呢?
    揭秘人工智能将如何影响今天的工作
    Linux为程序员添加了行为准则
    不可不知!4种常见的黑客攻击手段
  • 原文地址:https://www.cnblogs.com/zwjzwj/p/13150383.html
Copyright © 2020-2023  润新知