zoukankan      html  css  js  c++  java
  • Lexical Sign Sequence

    icpc的老题了,最近学校oj调出来拿来在训练赛做了,比赛的时候跟队友讨论了两种做法,一种是for循环加树状数组(分析了分析时间复杂度感觉虽然会t,但是应该不存在那种故意卡的数据,就直接交了,没想到一下就过了,于是第二种做法就没有实践),然而没想到比赛刚一结束学长反手就交了这样的一组hack数据卡掉了,QWQ。

    //#pragma GCC optimize(4)
    #include <bits/stdc++.h>
    #define rint register int
    typedef long long ll;
    using namespace std;
    const int N=100000+5;
    int a[N],b[N],c[N],vis[N],n,m;
    struct node
    {
        int x,y,z;
    }ar[N];
    void add(int x,int val)
    {
        for(int i=x;i<=n;i+=i&-i)c[i]+=val;
    }
    int ask(int x)
    {
        int ans=0;
        for(int i=x;i;i-=i&-i) ans+=c[i];
        return ans;
    }
    bool cmp(node s,node t)
    {
        return s.y<t.y;
    }
    int main()
    {
     
        ios::sync_with_stdio(false);
        cin.tie(0);
        cout.tie(0);
        cin>>n>>m;
        for(int i=1;i<=n;i++)
        {
            cin>>a[i];
            if(a[i]!=0)
            {
                vis[i]=1;
                add(i,a[i]);
            }
            else
            {
                add(i,-1);
                a[i]=-1;
            }
        }
        for(int i=1;i<=m;i++)
        {
            cin>>ar[i].x>>ar[i].y>>ar[i].z;
        }
        sort(ar+1,ar+1+m,cmp);
        int flag=0;
        for(int i=1;i<=m;i++)
        {
            int l=ar[i].x,r=ar[i].y;
            int sum=ask(r)-ask(l-1);
            for(int j=r;j>=l&&sum<ar[i].z;j--)
            {
                if(!vis[j])
                {
                    sum+=2;
                    add(j,2);
                    vis[j]=1;
                    a[j]=1;
                }
            }
            if(sum<ar[i].z)
            {
                flag=1;break;
            }
        }
        if(flag) printf("Impossible
    ");
        else
        {
            for(int i=1;i<n;i++)
            {
                printf("%d ",a[i]);
            }
            printf("%d
    ",a[n]);
        }
        return 0;
    }
     
    /**************************************************************
        Problem: 11753
        User: Qianwan063
        Language: C++
        Result: 时间超限
    ****************************************************************/

    另一种做法是借助了并查集,f[i]指向第一个可以变成1的位置,其他实现原理同上

    #pragma GCC optimize(4)
    #include <bits/stdc++.h>
    #define rint register int
    typedef long long ll;
    using namespace std;
    const int N=100000+5;
    int a[N],b[N],c[N],n,m,f[N];
    int getf(int x)
    {
        if(f[x]==x) return x;
        return f[x]=getf(f[x]);
       // return f[x]==x? x:f[x]=getf(f[x]);
    }
    struct node
    {
        int x,y,z;
    }ar[N];
    void add(int x,int val)
    {
        for(int i=x;i<=n;i+=i&-i)c[i]+=val;
    }
    int ask(int x)
    {
        int ans=0;
        for(int i=x;i;i-=i&-i) ans+=c[i];
        return ans;
    }
    bool cmp(node s,node t)
    {
        return s.y<t.y;
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        ios::sync_with_stdio(false);
        cin.tie(0);
        cout.tie(0);
        cin>>n>>m;
        for(int i=1;i<=n;i++) f[i]=i;
        for(int i=1;i<=n;i++)
        {
            cin>>a[i];
            if(a[i]!=0)
            {
                int x=getf(i);
                int y=getf(i-1);
                f[x]=y;
                add(i,a[i]);
            }
            else
            {
                add(i,-1);
                a[i]=-1;
            }
        }
        for(int i=1;i<=m;i++)
        {
            cin>>ar[i].x>>ar[i].y>>ar[i].z;
        }
        sort(ar+1,ar+1+m,cmp);
        int flag=0;
        for(int i=1;i<=m;i++)
        {
            int l=ar[i].x,r=ar[i].y;
            int sum=ask(r)-ask(l-1);
            int pos=r;
            while(sum<ar[i].z&&(pos=getf(pos))>=l)
            {
                sum+=2;
                add(pos,2);
                a[pos]=1;
                f[pos]=getf(pos-1);
            }
            if(sum<ar[i].z)
            {
                flag=1;break;
            }
        }
        if(flag) printf("Impossible
    ");
        else
        {
            for(int i=1;i<n;i++)
            {
                printf("%d ",a[i]);
            }
            printf("%d
    ",a[n]);
        }
        return 0;
    }
     
    /**************************************************************
        Problem: 11753
        User: Qianwan063
        Language: C++
        Result: 正确
        Time:53 ms
        Memory:6628 kb
    ****************************************************************/

     

  • 相关阅读:
    Linux中配置Aria2 RPC Server
    Ubuntu无法进入Windows的NTFS分区
    Visualbox在UEFI模式下无法正常引导
    pacman安装软件包出现损坏
    Windows下禁用锁屏热键WinKey+L
    Linux中无权限使用sudo
    Windows 10 MBR转GPT
    oh-my-zsh的安装与基本配置
    Raspbian开启root账户
    xrandr: 命令行修改分辨率工具
  • 原文地址:https://www.cnblogs.com/Suiyue-Li/p/11415200.html
Copyright © 2011-2022 走看看