多校冲刺 noip 11.07

多校冲刺 noip 11.07

今天挂了\(160pts\),本来\(AK\)了

这两天题真水,水展了。

T1 石子合并

考场上好久才想到只有一个减号的构造方法,最后因为没有判\(n==1\)挂成\(60pts\)

AC_code
#include<bits/stdc++.h>
using namespace std;
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
const int N=2e6+5;
const int inf=2e9+1;
int T,n,a[N];
int ans,mn,fl_del,fl_add,fl_nan;
signed main(){
    freopen("stone.in","r",stdin);
    freopen("stone.out","w",stdout);
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        fo(i,1,n)scanf("%d",&a[i]);
        ans=0;mn=inf;
        fl_add=fl_del=fl_nan=0;
        fo(i,1,n){
            if(a[i]>0)fl_add++;
            else if(a[i]<0)fl_del++;
            else fl_nan++;
            ans=max(ans+a[i],ans-a[i]);
            mn=min(mn,abs(a[i]));
        }
        if(fl_nan)ans=ans;
        else if(!fl_del)ans-=2*mn;
        else if(!fl_add)ans-=2*mn;
        if(n==1)ans=a[1];
        printf("%d\n",ans);
    }
    return 0;
}

T2 翻转游戏

一看这就是扫描线大板子!!于是有了下面这一百行

扫描线
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
const int N=3e5+5;
int T,p,q,n,ans;
int xa[N],xb[N],ya[N],yb[N];
struct scan{
    int x,yl,yr,tp;
    scan(){}
    scan(int a,int b,int c,int d){x=a;yl=b;yr=c;tp=d;}
    bool operator < (scan a)const{
        return x<a.x; 
    }
}sca[N];
int lsh[N*2],lh;
struct XDS{
    #define ls x<<1
    #define rs x<<1|1
    int s1[N*8],t1[N*8],s2[N*8],t2[N*8],tg[N*8];
    void pushup(int x){
        if(t1[ls]==t1[rs]){
            t1[x]=t1[ls],s1[x]=s1[ls]+s1[rs];
            t2[x]=max(t2[ls],t2[rs]);s2[x]=0;
            if(t2[ls]==t2[x])s2[x]+=s2[ls];
            if(t2[rs]==t2[x])s2[x]+=s2[rs];
        }
        else if(t1[ls]>t1[rs]){
            t1[x]=t1[ls],s1[x]=s1[ls];
            t2[x]=max(t2[ls],t1[rs]);s2[x]=0;
            if(t2[ls]==t2[x])s2[x]+=s2[ls];
            if(t1[rs]==t2[x])s2[x]+=s1[rs];
        }
        else {
            t1[x]=t1[rs],s1[x]=s1[rs];
            t2[x]=max(t2[rs],t1[ls]);s2[x]=0;
            if(t2[rs]==t2[x])s2[x]+=s2[rs];
            if(t1[ls]==t2[x])s2[x]+=s1[ls];
        }
        return ;
    }
    void pushdown(int x){
        tg[ls]+=tg[x];tg[rs]+=tg[x];
        t1[ls]+=tg[x];t2[ls]+=tg[x];
        t1[rs]+=tg[x];t2[rs]+=tg[x];
        tg[x]=0;return ;
    }
    void build(int x,int l,int r){
        tg[x]=0;
        if(l==r){
            t1[x]=0;s1[x]=lsh[l+1]-lsh[l];
            t2[x]=-1;s2[x]=0;
            return ;
        }
        int mid=l+r>>1;
        build(ls,l,mid);
        build(rs,mid+1,r);
        pushup(x);return ;
    }
    void ins(int x,int l,int r,int ql,int qr,int v){
        if(ql>qr)return ;
        if(ql<=l&&r<=qr){
            tg[x]+=v;t1[x]+=v;t2[x]+=v;
            return ;
        }
        if(tg[x])pushdown(x);
        int mid=l+r>>1;
        if(ql<=mid)ins(ls,l,mid,ql,qr,v);
        if(qr>mid)ins(rs,mid+1,r,ql,qr,v);
        pushup(x);return ;
    }
    #undef ls
    #undef rs
}xds;
signed main(){
    freopen("carpet.in","r",stdin);
    freopen("carpet.out","w",stdout);
    scanf("%lld",&T);
    while(T--){
        scanf("%lld%lld%lld",&p,&q,&n);ans=0;
        fo(i,1,n){
            scanf("%lld%lld%lld%lld",&xa[i],&ya[i],&xb[i],&yb[i]);
            lsh[i*2-1]=ya[i];lsh[i*2]=yb[i];
            sca[i*2-1]=scan(xa[i],ya[i],yb[i],1);
            sca[i*2]=scan(xb[i],ya[i],yb[i],-1);
        }lh=n*2;
        sort(lsh+1,lsh+lh+1);
        lh=unique(lsh+1,lsh+lh+1)-lsh-1;
        xds.build(1,1,lh);int sum;
        sort(sca+1,sca+2*n+1);
        fo(i,1,n*2){
            sca[i].yl=lower_bound(lsh+1,lsh+lh+1,sca[i].yl)-lsh;
            sca[i].yr=lower_bound(lsh+1,lsh+lh+1,sca[i].yr)-lsh-1;
            //cout<<sca[i].yl<<" "<<sca[i].yr<<endl;
            xds.ins(1,1,lh,sca[i].yl,sca[i].yr,sca[i].tp);
            if(i!=n*2){
                sum=(xds.t1[1]>=n-1?xds.s1[1]:0)+(xds.t2[1]>=n-1?xds.s2[1]:0);
                ans+=(sca[i+1].x-sca[i].x)*sum;
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}

于是只有\(50pts\)

于是发现只有\(n+1\)种情况,于是切掉了

AC_code
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
const int N=3e5+5;
int T,p,q,n,ans;
int xa[N],xb[N],ya[N],yb[N];
int pxa[N],pxb[N],pya[N],pyb[N];
void maxx(int x,int y,int z){
    pxa[z]=max(pxa[x],xa[y]);
    pxb[z]=min(pxb[x],xb[y]);
    pya[z]=max(pya[x],ya[y]);
    pyb[z]=min(pyb[x],yb[y]);
}
signed main(){
    freopen("carpet.in","r",stdin);
    freopen("carpet.out","w",stdout);
    scanf("%lld",&T);
    while(T--){
        scanf("%lld%lld%lld",&p,&q,&n);ans=0;
        fo(i,1,n){
            scanf("%lld%lld%lld%lld",&xa[i],&ya[i],&xb[i],&yb[i]);
        }
        memset(pxa,0,sizeof(pxa));
        memset(pxb,0x3f,sizeof(pxb));
        memset(pya,0,sizeof(pya));
        memset(pyb,0x3f,sizeof(pyb));
        fo(i,1,n)maxx(i-1,i,i);
        fu(i,n,1){
            pxa[n+1]=max(pxa[i-1],pxa[n+2]);
            pxb[n+1]=min(pxb[i-1],pxb[n+2]);
            pya[n+1]=max(pya[i-1],pya[n+2]);
            pyb[n+1]=min(pyb[i-1],pyb[n+2]);
            int x=pxb[n+1]-pxa[n+1];if(x<0)x=0;
            int y=pyb[n+1]-pya[n+1];if(y<0)y=0;
            ans+=x*y;
            maxx(n+1,i,n+1);
            x=pxb[n+1]-pxa[n+1];if(x<0)x=0;
            y=pyb[n+1]-pya[n+1];if(y<0)y=0;
            if(i!=1)ans-=x*y;
            maxx(n+2,i,n+2);
        }
        printf("%lld\n",ans);
    }
    return 0;
}

T3 优美的旋律

因为一个字写错了,挂掉\(60pts\)

咋做都行, 直接枚举

AC_code
#include<bits/stdc++.h>
using namespace std;
#define ull unsigned long long
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
const int N=3005;
const int bas=131;
int a,b,n,ans;
char s[N];
ull hs[N],ba[N],cf[N][N];
int ys[N][N],pd[N][N];
ull get(int l,int r){return hs[r]-hs[l-1]*ba[r-l+1];}
signed main(){
    freopen("melody.in","r",stdin);
    freopen("melody.out","w",stdout);
    // cout<<(sizeof(cf)*3>>20)<<endl;
    scanf("%d%d",&a,&b);
    scanf("%s",s+1);n=strlen(s+1);
    ba[0]=1;fo(i,1,n){
        ba[i]=ba[i-1]*bas;
        hs[i]=hs[i-1]*bas+s[i]-'a';
    }
    fo(i,1,n){
        cf[i][1]=1;
        fo(j,2,n/i)cf[i][j]=cf[i][j-1]*ba[i]+1;
    }
    fo(i,1,n){
        int now=i;
        fo(j,2,sqrt(now))
            if(now%j==0){
                ys[i][++ys[i][0]]=j;
                while(now%j==0)now/=j;
            }
        if(now!=1)ys[i][++ys[i][0]]=now;
    }
    fo(i,1,n){
        fo(j,1,i){
            ull ha=get(j,i);
            int len=i-j+1;
            if(!ys[len][0]){pd[j][i]=1;continue;}
            pd[j][i]=1;
            fo(k,1,ys[len][0]){
                if(get(j,len/ys[len][k]+j-1)*cf[len/ys[len][k]][ys[len][k]]==ha){
                    ans=max(ans,max(len/ys[len][k]*a+ys[len][k]*b,len/ys[len][k]/pd[j][len/ys[len][k]+j-1]*a+ys[len][k]*pd[j][len/ys[len][k]+j-1]*b));
                    pd[j][i]=ys[len][k]*pd[j][len/ys[len][k]+j-1];break;
                }
            }
        }
    }
    printf("%d",ans);
    return 0;
}

T4 基站建设

咋做都行,\(\mathcal{O(能过)}\)

AC_code
#include<bits/stdc++.h>
using namespace std;
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
const int N=50005;
const int M=2e5+5;
int n,m,ans;
int r[N];
int to[M*2],nxt[M*2],head[N],rp;
int du[N];
void add_edg(int x,int y){
    to[++rp]=y;
    nxt[rp]=head[x];
    head[x]=rp;
}
int fa[N],siz[N];
int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
vector<int> vec[N];
bool com(int x,int y){return x>y;}
void spj(){
    fo(i,1,n)vec[find(i)].push_back(r[i]);
    fo(i,1,n)if(find(i)==i){
        if(vec[i].size()<4)continue;
        sort(vec[i].begin(),vec[i].end(),com);
        ans=max(ans,(vec[i][0]+1)*(vec[i][1]+1)+vec[i][2]*vec[i][3]);
    }
    printf("%d",ans);
}
queue<int> q;
bool vis[N];
signed main(){
    freopen("station.in","r",stdin);
    freopen("station.out","w",stdout);
    scanf("%d%d",&n,&m);
    fo(i,1,n)scanf("%d",&r[i]);
    fo(i,1,n)fa[i]=i,siz[i]=1;
    fo(i,1,m){
        int x,y;scanf("%d%d",&x,&y);
        add_edg(x,y);add_edg(y,x);
        du[x]++;du[y]++;
        int fx=find(x),fy=find(y);
        if(fx==fy)continue;
        if(x<y)siz[fx]+=siz[fy],fa[fy]=fx;
        else siz[fy]+=siz[fx],fa[fx]=fy;
    }
    bool fl=true;
    fo(i,1,n)if(du[i]!=siz[find(i)]-1)fl=false;
    if(fl){spj();return 0;}
    int sb=clock();
    fo(i,1,n){
        for(int j=head[i];j;j=nxt[j])q.push(to[j]),vis[to[j]]=true;
        while(!q.empty()){
            int x=q.front(),mx=0,mi=0;q.pop();
            for(int j=head[x];j;j=nxt[j]){
                if(!vis[to[j]])continue;
                if(r[to[j]]>mx)mi=mx,mx=r[to[j]];
                else if(r[to[j]]>mi)mi=r[to[j]];
            }
            if(mx&&mi)ans=max(ans,(r[i]+1)*(r[x]+1)+mx*mi);
            if(clock()-sb>=5600000){printf("%d",ans);return 0;}
        }
        for(int j=head[i];j;j=nxt[j])vis[to[j]]=false;
    }
    printf("%d",ans);
    return 0;
}
上一篇:Python小题目3:输出指定标签下指定类型的文字


下一篇:多校冲刺 noip 11.06