其他分享
首页 > 其他分享> > NOIP 模拟 六十八

NOIP 模拟 六十八

作者:互联网

咕了十几场了,还是写一写吧。。

T1 玩水

发现满足三个人路径不同必须要有2个及以上的斜线相同结构,需要注意如果同一行或者同一列的话必须要相邻才行。

#include<bits/stdc++.h>
using namespace std;
char a[1050][1050];
int c[1050][1050],n,t,m;
inline void add(int x,int y,int val)
{   for(int i=x;i<=n;i+=i&-i)
    for(int j=y;j<=m;j+=j&-j)
    ++c[i][j];
}
inline int query(int x,int y)
{   int res=0;
    for(int i=x;i;i-=i&-i)
    for(int j=y;j;j-=j&-j)
    res+=c[i][j];
    return res;
}
signed main()
{   freopen("water.in","r",stdin);
    freopen("water.out","w",stdout);
    scanf("%d",&t);
    while(t--)
    {   int ji=0;
        scanf("%d%d",&n,&m); bool bo=0;
        for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)c[i][j]=0;
        for(int i=1;i<=n;++i)scanf("%s",a[i]+1);
        for(int i=2;i<=n;++i)
        {   for(int j=1;j<m;++j)
            {   if(a[i][j]==a[i-1][j+1])add(i,j,1);
                if(a[i][j]==a[i-1][j+1] and query(i,j)>=2){bo=1;break;}
            }if(bo)break;
        }
        if(n==2)
        {   bo=0;
            for(int i=1;i<m-1;++i)if(a[2][i]==a[1][i+1] and a[2][i+1]==a[1][i+2])bo=1;
        }
        if(bo)puts("1");
        else puts("0");
    }
    return 0;
}

T2 假人

待补。。

T3 切题

如果方案可行,对于最大的k个$a_i$ ,总有$\sum_{i=1}{m}min(b_i,k)>=\sum_{i=1}ka_i$。

将 b 的统计方式转换,设$c_i$为大于等于 i 的 b 的个数,那么上式为$\sum_{i-1}^{k}c_i$

于是可以线段树维护最小值。修改的话需要记录每个$a_i$的第一次和最后一次出现位置。

#include<bits/stdc++.h>
using namespace std;
int fir[564545],sec[554545];
int n,m,b[250001],a[250001],tmp[250001],q,val[250001],c[250001];
int minn[250010<<3],tag[250010<<3];
inline void pushup(int x){minn[x]=min(minn[x<<1],minn[x<<1|1]);}
inline void pushdown(int x){minn[x<<1]+=tag[x];minn[x<<1|1]+=tag[x];tag[x<<1]+=tag[x];tag[x<<1|1]+=tag[x];tag[x]=0;}
inline void build(int x,int l,int r)
{   if(l==r){minn[x]=val[l];return ;}
    int mid=(l+r)>>1;
    build(x<<1,l,mid);build(x<<1|1,mid+1,r);
    pushup(x);
}
inline void update(int x,int l,int r,int L,int R,int val)
{   if(l>=L and r<=R){minn[x]+=val;tag[x]+=val;return;}
    if(tag[x]!=0)pushdown(x);
    int mid=(l+r)>>1;
    if(mid<R)update(x<<1|1,mid+1,r,L,R,val);
    if(mid>=L)update(x<<1,l,mid,L,R,val);
    pushup(x);
}
signed main()
{   freopen("problem.in","r",stdin);
    freopen("problem.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i)scanf("%d",&a[i]),tmp[i]=a[i];
    for(int i=1;i<=m;++i)scanf("%d",&b[i]);
    sort(tmp+1,tmp+1+n);
    for(int i=1;i<=m;++i)c[min(b[i],n)]++;
    for(int i=n-1;i;--i)c[i]+=c[i+1];
    c[0]=0;for(int i=1;i<=n;++i)c[i]+=c[i-1];
    for(int i=n,sum=0;i;--i)
    {   sum+=tmp[i];
        val[n-i+1]=c[n-i+1]-sum;
    }
    for(int i=n;i;--i)if(!fir[tmp[i]])fir[tmp[i]]=n-i+1;
    for(int i=1;i<=n;++i)if(!sec[tmp[i]])sec[tmp[i]]=n-i+1; 
    build(1,1,n);scanf("%d",&q);
    for(int i=1;i<=q;++i)
    {   int opt,pos;
        scanf("%d%d",&opt,&pos);
        if(opt==1)
        {   int pre=a[pos];
            a[pos]++;
            int p=fir[pre];
            update(1,1,n,p,n,-1);
            if(!fir[a[pos]] and !sec[a[pos]])sec[a[pos]]=p;
            else fir[a[pos]]=p,sec[a[pos]]=p;
            if(fir[pre]==sec[pre])fir[pre]=sec[pre]=0;
            else fir[pre]=p+1;

            printf("%d\n",minn[1]>=0);
        }
        if(opt==2)
        {   int pre=a[pos];a[pos]--;
            int p=sec[pre];
            update(1,1,n,p,n,1);
            if(!fir[a[pos]] and !sec[a[pos]])fir[a[pos]]=p;
            else fir[a[pos]]=p,sec[a[pos]]=p;
             if(fir[pre]==sec[pre])fir[pre]=sec[pre]=0;
            else sec[pre]=p-1;
            printf("%d\n",minn[1]>=0);
        }
        if(opt==3)
        {   ++b[pos];
            if(b[pos]<=n)update(1,1,n,b[pos],n,1);   
            printf("%d\n",minn[1]>=0);
        }
        if(opt==4)
        {   --b[pos];
            if(b[pos]<n)update(1,1,n,b[pos]+1,n,-1);
            printf("%d\n",minn[1]>=0);
        }
    } 
}

T4 天下第一

LCT维护连通性不会,待补。。

标签:pre,fir,NOIP,int,pos,sec,250001,六十八,模拟
来源: https://www.cnblogs.com/zhaoxubing/p/15367872.html