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\n");
    else
    {
        for(int i=1;i<n;i++)
        {
            printf("%d ",a[i]);
        }
        printf("%d\n",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\n");
    else
    {
        for(int i=1;i<n;i++)
        {
            printf("%d ",a[i]);
        }
        printf("%d\n",a[n]);
    }
    return 0;
}
 
/**************************************************************
    Problem: 11753
    User: Qianwan063
    Language: C++
    Result: 正确
    Time:53 ms
    Memory:6628 kb
****************************************************************/

 

猜你喜欢

转载自www.cnblogs.com/Suiyue-Li/p/11415200.html
今日推荐