zoukankan      html  css  js  c++  java
  • [Codeforces #188] Tutorial

    Link:

    Codeoforces #188 传送门

    A:

    先全转为正数,后面就全是指数级增长了

    #include <bits/stdc++.h>
    
    using namespace std;
    #define X first
    #define Y second
    typedef long long ll;
    typedef pair<int,int> P;
    ll x,y,m,res;
    
    int main()
    {
        cin>>x>>y>>m;
        if(max(x,y)<m&&max(x,y)<=0) 
            return puts("-1"),0;
        
        while(x<m&&y<m)
        {
            if(x>y) swap(x,y);
            ll t=(y-x)/y+1;
            res+=t;x+=t*y;
        }
        cout<<res;
        return 0;
    }
    Problem A

    不断将$(x,y)$改为$(x+y,x)$要分类,在一数为负数时为线性增长

    B:

    首先要发现最终不为0的点的$x,y$的范围仅不到$[-100,100]$

    又由于最终状态和操作顺序无关,因此每次将可能区域内的点暴力更新即可

    不过我一开始使用了$bfs$,导致同一个位置可能每次进栈多次从而TLE……

    以后$bfs$在同一层时一定要控制每个数的进栈次数!能每个位置暴力就不要$bfs$

    #include <bits/stdc++.h>
    
    using namespace std;
    #define X first
    #define Y second
    typedef long long ll;
    typedef pair<int,int> P;
    const int ZERO=105;
    int n,t,x,y,a[2*ZERO][2*ZERO],flag=1;
    int dx[]={0,0,1,-1},dy[]={1,-1,0,0};
    
    int main()
    {
        scanf("%d%d",&n,&t);
        a[ZERO][ZERO]=n;
        while(flag)
        {
            flag=0;
            for(int i=ZERO-100;i<=ZERO+100;i++)
                for(int j=ZERO-100;j<=ZERO+100;j++)
                    if(a[i][j]>=4)
                    {
                        flag=1;
                        for(int k=0;k<4;k++)
                            a[i+dx[k]][j+dy[k]]+=a[i][j]/4;
                        a[i][j]%=4;
                    }
        }
        while(t--)
            scanf("%d%d",&x,&y),printf("%d
    ",abs(x)<=ZERO&&abs(y)<=ZERO?a[ZERO+x][ZERO+y]:0);
        return 0;
    }
    Problem B

    C:

    其实是一道不算难的模拟题?可能当时被吓到了……

    只要每个连通块里保证收支平衡就保证有解

    接下来可以暴力枚举点对转移,保证是将多出的转入少的中,这样就可以忽略上限这个条件了

    但也可以总共$O(n^2)$得做:

    由于转移次数上限为$O(2*n^2)$,因此可以仅将每个连通块连成一棵树

    将一个当前不够的点作为根先做一个预处理,只要$O(n)$的遍历就能使该点符合条件

    过程中注意保证已经符合条件的点不能改变,将当前多出的转移

    #include <bits/stdc++.h>
    
    using namespace std;
    #define X first
    #define Y second
    typedef long long ll;
    typedef pair<int,int> P;
    const int MAXN=2e5+10;
    struct edge{int nxt,to;}e[MAXN<<2];
    struct result{int x,y,val;}res[MAXN<<2];
    int n,v,m,x,y,a[MAXN],b[MAXN],f[MAXN],head[MAXN],tot,cnt;ll sum[MAXN];
    
    int find(int x)
    {return f[x]==x?x:f[x]=find(f[x]);}
    void add_edge(int x,int y)
    {e[++tot]={head[x],y};head[x]=tot;e[++tot]={head[y],x};head[y]=tot;}
    void add_res(int x,int y,int val)
    {a[x]-=val,a[y]+=val,res[++cnt]={x,y,val};}
    
    void dfs(int x,int anc)
    {
        sum[x]=a[x]-b[x];
        for(int i=head[x];i;i=e[i].nxt)
            if(e[i].to!=anc) dfs(e[i].to,x),sum[x]+=sum[e[i].to];
    }
    void solve(int x,int anc,int val)
    {
        for(int i=head[x];i;i=e[i].nxt)
        {
            if(e[i].to==anc||sum[e[i].to]<=0) continue; 
            int w=sum[e[i].to]<val?sum[e[i].to]:val,tmp=a[e[i].to];
            if(tmp>=w)
            {
                add_res(e[i].to,x,w);
                if(a[e[i].to]<b[e[i].to]&&tmp>=b[e[i].to]) 
                    solve(e[i].to,x,b[e[i].to]-a[e[i].to]);
            }
            else
            {
                add_res(e[i].to,x,tmp);
                if(tmp<b[e[i].to]) solve(e[i].to,x,w-tmp);
                else solve(e[i].to,x,w-tmp+b[e[i].to]);
                add_res(e[i].to,x,w-tmp);
            }
            val-=w;if(!val) return;
        }
    }
    
    int main()
    {
        scanf("%d%d%d",&n,&v,&m);
        for(int i=1;i<=n;i++) f[i]=i;
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        for(int i=1;i<=n;i++) scanf("%d",&b[i]);
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&x,&y);
            int posx=find(x),posy=find(y);
            if(posx!=posy) add_edge(x,y),f[posx]=posy;
        }
        for(int i=1;i<=n;i++) sum[find(i)]+=a[i]-b[i];
        for(int i=1;i<=n;i++) if(sum[i]) return puts("NO"),0;
        
        for(int i=1;i<=n;i++)
            if(a[i]<b[i]) dfs(i,0),solve(i,0,b[i]-a[i]);
        printf("%d
    ",cnt);
        for(int i=1;i<=cnt;i++)
            printf("%d %d %d
    ",res[i].x,res[i].y,res[i].val);
        return 0;
    }
    Problem C

    D:

    很明显的一道博弈论

    找到所有极大的集合${X^s}$,对每个集合求$SG$值最后异或即可

    其中数量大于2的集合可以$sqrt(n)$得找出,剩下数量为1的$SG=1$,可以统一计算

    同时$SG$值仅和集合内数量相关,可以预处理+打表

    #include <bits/stdc++.h>
    
    using namespace std;
    #define X first
    #define Y second
    typedef long long ll;
    typedef pair<int,int> P;
    const int mx=30,MAXN=1e5+10;
    //unordered_map<int,int> mp;
    int n,k,pre[50],vis[MAXN],rem,res;
    int sg[30]={0,1,2,1,4,3,2,1,5,6,2,1,8,7,5,9,8,7,3,4,7,4,2,1,10,9,3,6,11,12};
    /*
    int solve(int x)
    {
        int &tmp=mp[x];
        if(tmp) return tmp;
        int ret=(1<<mx)-1;
        for(int i=1;(1<<(i-1))<=x;i++)
            if(x&(1<<(i-1)))
                ret&=~solve(x&~pre[i]);
        return tmp=ret&(-ret);
    }
    */
    int main()
    {
    /*    
        for(int i=1;i<=mx;i++)
            for(int j=i;j<=mx;j+=i)
                pre[i]|=(1<<(j-1));        
        mp.max_load_factor(0.30);
        mp.reserve(750000);
        for(int i=1;i<mx;i++)
            sg[i]=__builtin_ctz(solve((1<<i)-1));
    */    
        scanf("%d",&n);
        rem=n;res=0;
        for(int i=2;i*i<=n;i++)
            if(!vis[i])
            {
                k=0;
                for(ll j=i;j<=n;j*=i,k++) 
                    if(j*j<=n) vis[j]=1;
                rem-=k;res^=sg[k];
            }
        res^=(rem&1);
        puts(res?"Vasya":"Petya");
        return 0;
    }
    Problem D

    与次方相关的注意将大于1的和1次方分开考虑

    注意该题各种位运算技巧和$unordered\_ map$以及$builtin\_ ctz,reserve(),max\_load\_factor$的使用

    E:

  • 相关阅读:
    Kinect学习笔记(六)——深度数据测量技术及应用
    [device]/proc/devices and /dev/
    [Eth]Mac/Phy/mdio/Rgmii
    [uboot]uboot如何引导系统
    [网络]Linux一些网络知识
    [基础]sizeof和strlen
    [基础]关于extern指针和数组的用法
    [ucos]了解ucos
    [Linux]gcc/libc/glibc
    [i.MX6q]i.MX6q处理器,linux操作系统平台搭建 从SD卡启动系统
  • 原文地址:https://www.cnblogs.com/newera/p/9567546.html
Copyright © 2011-2022 走看看