noip模拟69[挂分大法好]

noip模拟69 solutions

考得非常拉,拉爆了!!!

关于我挂分这个事,我不知道我为什么已经两次没有看全题了

这次本来输出两个数,我只输出了第二个,挂掉50

但是我到极限也只有\(180pts\),所以我还是菜了

T1 石子游戏

不会,我只有\(50pts\),直接超级大暴力\(SG\)函数

AC_code
#include<bits/stdc++.h>
using namespace std;
#define oj
#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=5e5+5;
int n,a[N],sg[N];
bool vis[N];
int na[N],cnt;
signed main(){
    #ifdef oj
        freopen("stone.in","r",stdin);
        freopen("stone.out","w",stdout);
    #endif
    scanf("%d",&n);
    fo(i,1,n){
        scanf("%d",&a[i]);
        if(vis[a[i]])vis[a[i]]=false;
        else vis[a[i]]=true;
    }
    fo(i,1,n)if(vis[i])na[++cnt]=i;
    fo(k,1,n){
        int ans=0;
        fo(i,1,cnt)ans^=na[i]%(k+1);
        if(ans)printf("Alice ");
        else printf("Bob ");
    }
}

好啦好啦我会\(100pts\)的做法了

首先我们理解这个dp,对于\(-i\)这个限制来说,我想让\(j\)这一位是1,它加上\(1<<j+1\)之后的这一位 仍然是合法的

那么我们考虑\(i~i+(1<<j+1)-1\)这个区间之内的,这个直接用我们预处理出来的\(c\)数组就好了

考虑如何利用这个数组得到答案,我们枚举\(x\)的大小

每次去遍历每一位,这是一个\(log\),枚举每一个块,这应该是\(ln\),反正都差不多

我们先用\(dp\)数组加减一下,在处理一下散块,为什么会出现散块,因为处理的时候是一块一块处理的

AC_code
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define fxt(i,x,y) for(int i=(x);i<=(y);i++)
#define pyt(i,x,y) for(int i=(x);i>=(y);i--)
const int N=1e6+5;
int n,a[N],f[N<<2][22],c[N<<2],mx;
signed main(){
    freopen("stone.in","r",stdin);
    freopen("stone.out","w",stdout);
    scanf("%lld",&n);
    fxt(i,1,n){
        scanf("%lld",&a[i]);
        c[a[i]]++;
        mx=max(mx,a[i]);
    }
    fxt(i,1,N<<1)c[i]+=c[i-1];
    pyt(i,mx,0)fxt(j,0,19)f[i][j]=f[i+(1<<j+1)][j]+c[i+(1<<j+1)-1]-c[i+(1<<j)-1];
    fxt(x,1,n){
        int k=n/(x+1);
        bool flag=false;
        fxt(i,0,19){
            int res=0;
            fxt(j,0,k){
                int l=j*(x+1),r=(j+1)*(x+1)-1;
                int num=(r-l+1)/(1<<i+1);
                res+=(num?f[l][i]-f[l+num*(1<<i+1)][i]:0)+max(0ll,c[r]-c[l+num*(1<<i+1)+(1<<i)-1]);
            }
            if(res&1){flag=true;break;}
        }
        if(flag)printf("Alice ");
        else printf("Bob ");
    }
}

T2 大鱼吃小鱼

这个会是会了,但是还没有打出来

不打啦不打啦!!!!

好像是差不多了\(88pts\)但是有点抵触这个题了,不想调了

88pts
#include<bits/stdc++.h>
using namespace std;
namespace FXT{
    #define oj
    #define int long long
    #define fxt(i,x,y) for(int i=(x);i<=(y);i++)
    #define pyt(i,x,y) for(int i=(x);i>=(y);i--)
    const int N=1e6+5;
    const int inf=0x7fffffffffffffff;
    int n,q,sca[N],qus[N][3];
    int lsh[N*2],lh;
    multiset<int> st;
    struct XDS{
        #define ls x<<1
        #define rs x<<1|1
        int sum[N*8],cnt[N*8];
        int bin[N*8][5],tot,vis[N*8];
        int pos,sm;
        void bi(int x,int l,int r){
            if(vis[x])return ;
            bin[++tot][0]=x;
            bin[tot][1]=sum[x];
            bin[tot][2]=cnt[x];
            bin[tot][3]=l;
            bin[tot][4]=r;
            sum[x]=cnt[x]=0;
            vis[x]=true;
        }
        void hf(int x,int l,int r,int ql,int qr,int sm,int ct){
            if(ql<=l&&r<=qr)return sum[x]=sm,cnt[x]=ct,void();
            int mid=l+r>>1;
            if(ql<=mid)hf(ls,l,mid,ql,qr,sm,ct);
            else hf(rs,mid+1,r,ql,qr,sm,ct);
            pushup(x);return ;
        }
        void hy(){
            pyt(i,tot,1){
                hf(1,1,lh,bin[i][3],bin[i][4],bin[i][1],bin[i][2]);
                //sum[bin[i][0]]=bin[i][1];
                //cnt[bin[i][0]]=bin[i][2];
                vis[bin[i][0]]=false;
            }
            tot=0;
            return ;
        }
        void pushup(int x){
            cnt[x]=cnt[ls]+cnt[rs];
            sum[x]=sum[ls]+sum[rs];
            return ;
        }
        void ins(int x,int l,int r,int pos,int v){
            if(l==r){
                sum[x]+=v*lsh[pos];cnt[x]+=v;
                //cout<<"ins "<<x<<" "<<l<<" "<<r<<" "<<pos<<" "<<v<<endl;
                return ;
            }
            int mid=l+r>>1;
            if(pos<=mid)ins(ls,l,mid,pos,v);
            else ins(rs,mid+1,r,pos,v);
            pushup(x);return ;
        }
        void query(int x,int l,int r,int qr){
            if(pos||l>qr)return ;
            int mid=l+r>>1;
            if(r<=qr){
                if(l==r){
                    if(sum[x]>=sm){
                        pos=l;
                        //if(sm>=0)cout<<"xds"<<" "<<l<<" "<<r<<" "<<qr<<" "<<sum[x]<<" "<<sm<<endl;
                    }
                    else sm-=sum[x];
                    return ;
                }
                if(sum[rs]>=sm)query(rs,mid+1,r,qr);
                else sm-=sum[rs],query(ls,l,mid,qr);
                return ;
            }
            query(rs,mid+1,r,qr);
            query(ls,l,mid,qr);
            return ; 
        }
        int Sum(int x,int l,int r,int ql,int qr){
            if(ql<=l&&r<=qr)return sum[x];
            int mid=l+r>>1,ret=0;
            if(ql<=mid)ret+=Sum(ls,l,mid,ql,qr);
            if(qr>mid)ret+=Sum(rs,mid+1,r,ql,qr);
            return ret;
        }
        int Cnt(int x,int l,int r,int ql,int qr){
            if(ql<=l&&r<=qr)return cnt[x];
            int mid=l+r>>1,ret=0;
            if(ql<=mid)ret+=Cnt(ls,l,mid,ql,qr);
            if(qr>mid)ret+=Cnt(rs,mid+1,r,ql,qr);
            return ret;
        }
        void del(int x,int l,int r,int ql,int qr){
            if(ql<=l&&r<=qr)return bi(x,l,r),void();
            int mid=l+r>>1;
            if(ql<=mid)del(ls,l,mid,ql,qr);
            if(qr>mid)del(rs,mid+1,r,ql,qr);
            pushup(x);return ;
        }
        #undef ls
        #undef rs
    }xds;
    int R=1e18;
    signed main(){
        #ifdef oj
            freopen("fish.in","r",stdin);
            freopen("fish.out","w",stdout);
        #endif
        scanf("%lld",&n);
        fxt(i,1,n)scanf("%lld",&sca[i]),lsh[++lh]=sca[i];
        scanf("%lld",&q);
        fxt(i,1,q){
            scanf("%lld%lld",&qus[i][0],&qus[i][1]);lsh[++lh]=qus[i][1];
            if(qus[i][0]==1)scanf("%lld",&qus[i][2]),lsh[++lh]=qus[i][2];
        }
        sort(lsh+1,lsh+lh+1);
        fxt(i,1,n)sca[i]=lower_bound(lsh+1,lsh+lh+1,sca[i])-lsh,lsh[sca[i]]--;
        fxt(i,1,q){
            qus[i][1]=lower_bound(lsh+1,lsh+lh+1,qus[i][1])-lsh,lsh[qus[i][1]]--;
            if(qus[i][0]==1)qus[i][2]=lower_bound(lsh+1,lsh+lh+1,qus[i][2])-lsh,lsh[qus[i][2]]--;
        }
        fxt(i,1,lh)lsh[i]++;
        fxt(i,1,n)xds.ins(1,1,lh,sca[i],1),st.insert(lsh[sca[i]]);//cout<<sca[i]<<" "<<lsh[sca[i]]<<endl;
        fxt(i,1,q){
            if(qus[i][0]==1){
                int x=lsh[qus[i][1]],y=lsh[qus[i][2]];
                bool flag=false;int ans=0;
                while(x<y){
                    xds.sm=min(st.lower_bound(x)==st.end()?inf:*st.lower_bound(x),y-1)-x+1;xds.pos=0;
                    int r=lower_bound(lsh+1,lsh+lh+1,x)-lsh-1;
                    xds.query(1,1,lh,r);//cout<<x<<" "<<xds.pos<<endl;
                    //if(x!=15)cout<<i<<" "<<xds.sm<<" "<<xds.pos<<" "<<r<<" "<<x<<" "<<y<<endl;
                    if(!xds.pos)break;
                    //cout<<x<<" "<<xds.pos<<" ";
                    x+=xds.Sum(1,1,lh,xds.pos,r);
                    //cout<<x<<endl;
                    //if(x<y&&xds.pos==1)break;
                    ans+=xds.Cnt(1,1,lh,xds.pos,r);
                    xds.del(1,1,lh,xds.pos,r);
                }
                xds.hy();
                if(x<y)printf("-1\n");
                else printf("%lld\n",ans);
            }
            if(qus[i][0]==2)xds.ins(1,1,lh,qus[i][1],1),st.insert(lsh[qus[i][1]]);
            if(qus[i][0]==3)xds.ins(1,1,lh,qus[i][1],-1),st.erase(lsh[qus[i][1]]);
        }
        return 0;
    } 
}
signed main(){return FXT::main();}

T3 黑客 first

直接\(\mathcal{O(n^2)}\)枚举

考场上竟然没有想出来。。。。。

AC_code
#include<bits/stdc++.h>
using namespace std;
#define oj
#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 mod=1e9+7;
int A,B,C,D,ans,mx;
int gcd(int x,int y){return y==0?x:gcd(y,x%y);}
signed main(){
    #ifdef oj
        freopen("hacker.in","r",stdin);
        freopen("hacker.out","w",stdout);
    #endif
    scanf("%lld%lld%lld%lld",&A,&B,&C,&D);
    fo(i,1,999){
        int t1=(A-1)/i;
        int t2=B/i;
        fo(j,1,999-i){
            if(gcd(i,j)!=1)continue; 
            int t3=(C-1)/j;
            int t4=D/j;
            int tmp=min(t4,t2)-max(t1,t3);
            if(tmp>0)ans=(ans+tmp%mod*(i+j))%mod;//cout<<i<<" "<<j<<" "<<tmp<<endl;
        }
    }
    printf("%lld",ans);
}

T4 黑客 second

这个也挺好想的,就是被高精吓到了,然后就直接打部分分去了

我是枚举的之前的状态,然后只能卡常过,

\(zxb\)枚举不合法的状态转移,比我快十倍

AC_code
#include<bits/stdc++.h>
using namespace std;
#define oj
#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=505;
const int p=1e8;
int n,m,k,U;
struct GJD{
    int x[125];
    GJD(){memset(x,0,sizeof(x));}
    GJD operator + (GJD a)const{
        GJD ret;int ys=0;ret.x[0]=max(x[0],a.x[0]);
        fo(i,1,max(x[0],a.x[0])+1){
            int tmp=x[i]+a.x[i]+ys;
            if(tmp)ret.x[0]=i;
            ret.x[i]=tmp%p;
            ys=tmp/p;
        }
        return ret;
    }
    GJD operator * (int a)const{
        GJD ret;fo(i,1,x[0])ret.x[i]=x[i]*a;
        fo(i,1,x[0]+1){
            if(ret.x[i])ret.x[0]=i;
            ret.x[i+1]+=ret.x[i]/p;
            ret.x[i]%=p;
        }
        return ret;
    }
};
int mi[N];
GJD get(GJD a,int y){
    int tmp=y/8;
    GJD ret;
    fo(i,1,a.x[0])ret.x[i+tmp]=a.x[i];
    ret.x[0]=a.x[0]+tmp;
    fo(i,1,y%8)ret=ret*10;
    return ret;
}
struct node{
    GJD fas,sum;
    bool pd;
    node(){}
    node operator + (node a)const{
        node ret;
        ret.fas=fas+a.fas;
        ret.sum=sum+a.sum;
        return ret;
    }
}f[N][1<<9];
void print(GJD a){
    int pos=a.x[0];
    printf("%d",a.x[pos]);
    fu(i,pos-1,1)printf("%.8d",a.x[i]);
    printf("\n");
}
vector<int> who[10];
bool vis[10],can[1<<9][10];
int ca[1<<9];
vector<int> jus[1<<9];
void dfs(int x,int t){
    if(x==n+1){
        f[x][t].pd=true;
        f[x][t].fas.x[1]=1;
        f[x][t].fas.x[0]=1;
        return ;
    }
    node now;fo(i,1,k)if(can[t][i]){
        if(!f[x+1][t|(1<<i-1)].pd)dfs(x+1,t|(1<<i-1));
        f[x][t].fas=f[x][t].fas+f[x+1][t|(1<<i-1)].fas;
        f[x][t].sum=f[x][t].sum+f[x+1][t|(1<<i-1)].sum;
        now.sum=now.sum+f[x+1][t|(1<<i-1)].fas*i;
    }
    now.sum=get(now.sum,n-x);
    f[x][t]=f[x][t]+now;
    f[x][t].pd=true;
    fo(i,0,(int)jus[t].size()-1){f[x][jus[t][i]]=f[x][t];}
    return ;
}
signed main(){
    #ifdef oj
        freopen("hacker2.in","r",stdin);
        freopen("hacker2.out","w",stdout);
    #endif
    scanf("%d%d%d",&n,&m,&k);
    fo(i,1,m){
        int x,y;scanf("%d%d",&x,&y);
        who[x].push_back(y);
    }
    U=(1<<k)-1;
    fo(s,0,U){
        memset(vis,false,sizeof(vis));
        fo(i,1,k)if((1<<i-1)&s)fo(j,0,(int)who[i].size()-1)vis[who[i][j]]=true;
        fo(i,1,k)if(!vis[i])can[s][i]=true,ca[s]|=(1<<i-1);
    }
    fo(s,0,U)fo(ss,s+1,U)if(ca[s]==ca[ss]){jus[ss].push_back(s);jus[s].push_back(ss);}
    dfs(1,0);
    print(f[1][0].fas);
    print(f[1][0].sum);
}
posted @ 2021-10-07 20:47  fengwu2005  阅读(65)  评论(0编辑  收藏  举报