省选摩你35

似乎又垫底了,于是完蛋了,场均切第二题,我就啥也没看出来,打表能力有待提升

T1 Board Game

垃圾博弈dp,压位转移,强行优化

AC_code
#include<bits/stdc++.h>
using namespace std;
// #define int 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--)
int read(){
    int s=0,t=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')t=-1;ch=getchar();}
    while(isdigit(ch)){s=(s<<1)+(s<<3)+(ch^48);ch=getchar();}
    return s*t;
}
const int N=1<<22;
int n,m,k,h,w;
int id[30][30],cid,u,v;
unsigned long long dp[N],vis[N],zy1[65],zy2[65],a[30][30];
char ch[30];
signed main(){
    freopen("game.in","r",stdin);
    freopen("game.out","w",stdout);
    n=read();m=read();k=read();
    fo(i,1,n)fo(j,1,m)id[i][j]=++cid;
    u=(1<<cid-6)-1;v=(1ull<<64)-1;
    fo(kk,1,k){
        h=read();w=read();
        fo(i,1,h){
            scanf("%s",ch+1);
            fo(j,1,w)a[i][j]=ch[j]-'0';
        }
        fo(s,1,n-h+1)fo(t,1,m-w+1){
            int zt=0;
            fo(i,1,h)fo(j,1,w)zt|=a[i][j]<<(id[i+s-1][j+t-1]-1);
            vis[zt>>6]|=(1ull<<(zt&63));
        }
    }
    fo(i,0,63){
        fo(j,1,6){
            if((i>>j-1&1))zy1[i]|=(1ull<<(i^(1ull<<j-1)));
            else zy2[i]|=(1ull<<(i^(1ull<<j-1)));
        }
    }
    fo(s,0,u){
        int bit=s;
        for(int i=bit;i;i-=(i&-i))vis[s]|=vis[s^(i&-i)];
        fo(i,0,63)if(!(vis[s]>>i&1)){
            if(zy1[i]&vis[s])vis[s]|=(1ull<<i);
        }
    }
    fu(s,u,0){
        int bit=u^s;
        for(int i=bit;i;i-=(i&-i))dp[s]|=dp[s^(i&-i)];
        fu(i,63,0){
            if((vis[s]>>i&1)){
                dp[s]&=v^(1ull<<i);
                continue;
            }
            if((zy2[i]&dp[s])!=zy2[i])dp[s]|=(1ull<<i);
        }
        dp[s]=v^dp[s];
    }
    printf((dp[0]&1)==0?"Alice":"Bob");
    return 0;
}

T2 Function Query

发现操作其实是\(f(a,b) \Longrightarrow f(2*a\%(a+b),2*b\%(a+b))\)

简单推导即可得到操作次数就是(a+b)/gcd(a,b)是2的几次方,如果不是就是无解

于是我们发现这样的数之后\(log^2\)对,于是咋写都行,一种方式是枚举和是多少..

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--)
int read(){
    int s=0,t=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')t=-1;ch=getchar();}
    while(isdigit(ch)){s=(s<<1)+(s<<3)+(ch^48);ch=getchar();}
    return s*t;
}
const int N=1e5+5;
int n,Q,a[N],ps[N];
struct BIT{
    int tr[N];
    void ins(int x,int v){
        for(int i=x;i<=n;i+=(i&-i))tr[i]+=v;
    }
    int query(int x){
        int ret=0;
        for(int i=x;i;i-=(i&-i))ret+=tr[i];
        return ret;
    }
    int qry(int l,int r){
        return query(r)-query(l-1);
    }
}bit;
struct QU{int l,r,ans;}q[N];
vector<pair<int,int> > vec[N];
vector<int> add[N],del[N];
signed main(){
    freopen("func.in","r",stdin);
    freopen("func.out","w",stdout);
    n=read();
    fo(i,1,n)a[i]=read(),ps[a[i]]=i;
    Q=read();
    fo(i,1,Q){
        q[i].l=read();q[i].r=read();
        add[q[i].l].push_back(i);
        del[q[i].r+1].push_back(i);
    }
    fo(g,1,n){
        for(int i=1;i*g<=n;i+=2){
            int now=2,pw=1;
            while((now-i)*g<=n){
                if(now-i>0&&now-i!=i){
                    if(ps[i*g]<ps[(now-i)*g])vec[ps[i*g]].push_back(make_pair(ps[(now-i)*g],pw));
                    else vec[ps[(now-i)*g]].push_back(make_pair(ps[i*g],pw));
                }
                now*=2;pw++;
            }
        }
    }
    fu(i,n,1){
        for(pair<int,int> x:vec[i]){
            // cerr<<a[i]<<" "<<a[x.first]<<" "<<x.second<<endl;
            bit.ins(x.first,x.second);
        }
        for(int x:del[i])q[x].ans-=bit.qry(q[x].l,q[x].r);
        for(int x:add[i])q[x].ans+=bit.qry(q[x].l,q[x].r);
    }
    fo(i,1,Q)printf("%lld\n",q[i].ans/2);
    return 0;
}

T3 Minimal DFA

分析有限状态自动机的性质,这里的字符集是0、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--)
int read(){
    int s=0,t=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')t=-1;ch=getchar();}
    while(isdigit(ch)){s=(s<<1)+(s<<3)+(ch^48);ch=getchar();}
    return s*t;
}
const int N=1025;
const int B=1e9;
struct BIG{
    vector<int> x;
    BIG(){x.push_back(0);}
    BIG operator + (BIG a)const{
        if(!x.size())return a;
        if(!a.x.size())return *this;
        BIG ret;ret.x.resize(50);
        ret.x[0]=max(x[0],a.x[0]);
        int ys=0;
        fo(i,1,ret.x[0]){
            if(i>x[0])ret.x[i]=a.x[i]+ys;
            else if(i>a.x[0])ret.x[i]=x[i]+ys;
            else ret.x[i]=x[i]+a.x[i]+ys;
            ys=ret.x[i]/B;
            ret.x[i]%=B;
        }
        if(ys)ret.x[++ret.x[0]]=ys;
        while(ret.x.size()>ret.x[0]+1)ret.x.pop_back();
        return ret;
    }
    BIG operator - (BIG a)const{
        if(!a.x.size())return *this;
        BIG ret;ret.x.resize(50);
        ret.x[0]=x[0];
        fo(i,1,ret.x[0]){
            if(i>a.x[0])ret.x[i]+=x[i];
            else ret.x[i]+=x[i]-a.x[i];
            if(ret.x[i]<0)ret.x[i]+=B,ret.x[i+1]--;
        }
        while(!ret.x[ret.x[0]]&&ret.x[0]>1)ret.x[0]--;
        while(ret.x.size()>ret.x[0]+1)ret.x.pop_back();
        return ret;
    }
    BIG operator + (int a)const{
        BIG ret;ret.x.resize(50);
        fo(i,0,x[0])ret.x[i]=x[i];
        ret.x[1]+=a;
        fo(i,1,ret.x[0]){
            ret.x[i+1]+=ret.x[i]/B;
            ret.x[i]%=B;
        }
        if(ret.x[ret.x[0]+1])ret.x[0]++;
        while(ret.x.size()>ret.x[0]+1)ret.x.pop_back();
        return ret;
    }
    BIG operator - (int a)const{
        BIG ret;ret.x.resize(50);
        // cerr<<x[0]<<" "<<x[1]<<endl;
        fo(i,0,x[0])ret.x[i]=x[i];
        // cerr<<ret.x[i]<<" ";cerr<<endl;
        // ret=*this;
        ret.x[1]-=a;
        fo(i,1,ret.x[0]){
            if(ret.x[i]<0)ret.x[i]+=B,ret.x[i+1]--;
        }
        if(!ret.x[ret.x[0]]&&ret.x[0]>1)ret.x[0]--;
        while(ret.x.size()>ret.x[0]+1)ret.x.pop_back();
        return ret;
    }
    BIG operator * (int a)const{
        BIG ret;ret.x.resize(50);
        ret.x[0]=x[0];
        fo(i,1,ret.x[0]){
            ret.x[i]+=x[i]*a;
            ret.x[i+1]+=ret.x[i]/B;
            ret.x[i]%=B;
        }
        while(ret.x[ret.x[0]+1]){
            ret.x[0]++;
            ret.x[ret.x[0]+1]+=ret.x[ret.x[0]]/B;
            ret.x[ret.x[0]]%=B;
        }
        while(ret.x.size()>ret.x[0]+1)ret.x.pop_back();
        return ret;
    }
    BIG operator * (BIG a)const{
        BIG ret;ret.x.resize(50);
        ret.x[0]=x[0]+a.x[0]-1;
        fo(i,1,x[0])fo(j,1,a.x[0]){
            ret.x[i+j-1]+=x[i]*a.x[j];
            ret.x[i+j]+=ret.x[i+j-1]/B;
            ret.x[i+j-1]%=B;
        }
        fo(i,1,ret.x[0]){
            ret.x[i+1]+=ret.x[i]/B;
            ret.x[i]%=B;
        }
        while(ret.x[ret.x[0]+1]){
            // cerr<<ret.x[0]<<endl;
            ret.x[0]++;
            ret.x[ret.x[0]+1]+=ret.x[ret.x[0]]/B;
            ret.x[ret.x[0]]%=B;
        }
        while(ret.x.size()>ret.x[0]+1)ret.x.pop_back();
        return ret;
    }
    bool operator < (BIG a)const{
        if(x[0]<a.x[0])return true;
        if(x[0]>a.x[0])return false;
        fu(i,x[0],1){
            if(x[i]<a.x[i])return true;
            if(x[i]>a.x[i])return false;
        }
        return false;
    }
    bool operator <= (BIG a)const{
        if(x[0]<a.x[0])return true;
        if(x[0]>a.x[0])return false;
        fu(i,x[0],1){
            if(x[i]<a.x[i])return true;
            if(x[i]>a.x[i])return false;
        }
        return true;
    }
    BIG min(BIG a,BIG b)const{
        if(a<b)return a;
        return b;
    }
    void print(){
        printf("%lld",x[x[0]]);
        fu(i,x[0]-1,1)printf("%09lld",x[i]);
        printf(" ");
    }
}a[N],b[N],ans,mii,maa,c[N][N];
int n;
void sol1(int ps){
    if(ps+1==n)mii=b[ps+1];
    else mii=(b[ps+1]+1)*(1ll<<(n-ps-2));
    maa=mii+(a[ps+1]-b[ps+1])*(1ll<<(n-ps-1));
}
void sol2(int ps){
    if(ps+1==n){
        mii=b[ps+1]+1;
        maa=b[ps+1]+2;
        return ;
    }
    mii=(b[ps+1]+1)*(1ll<<(n-ps-2));
    BIG res=a[ps]-b[ps+1];
    fo(i,1,1ll<<n-ps){
        BIG now=c[1ll<<n-ps][i]-c[1ll<<n-ps-1][i];
        if(res<=now){
            mii=mii+res*i;
            break;
        }
        mii=mii+now*i;
        res=res-now;
    }
    maa=(b[ps+1]+1)*(1ll<<(n-ps-2))+(b[ps+1])*(1ll<<(n-ps-1));
    res=a[ps]-b[ps+1];
    fu(i,1ll<<n-ps,1){
        BIG now=c[1ll<<n-ps][i];
        if(i>(1ll<<n-ps-1))now=now-c[1ll<<n-ps-1][i-(1ll<<n-ps-1)];
        if(res<=now){
            maa=maa+res*i;
            break;
        }
        maa=maa+now*i;
        res=res-now;
    }
}
signed main(){
    freopen("dfa.in","r",stdin);
    freopen("dfa.out","w",stdout);
    n=read();
    fo(i,0,1024){
        c[i][0].x.resize(2);
        c[i][0].x[0]=1;c[i][0].x[1]=1;
        fo(j,1,i)c[i][j]=(c[i-1][j-1]+c[i-1][j]);
    }
    a[0].x.resize(2);
    a[0].x[0]=1;a[0].x[1]=1;
    fo(i,1,n)a[i]=a[i-1]+a[i-1];
    b[n].x.resize(2);
    b[n].x[0]=1;b[n].x[1]=1;
    fu(i,n-1,0){
        b[i]=(b[i+1]+1)*(b[i+1]+1)-1;
        if(a[i]<b[i]){
            if(a[i]<=b[i+1])sol1(i);
            else sol2(i);
            fo(j,0,i)ans=ans+a[j];
            fo(j,i+1,n)ans=ans+b[j];
            break;
        }
    }
    ans.print();mii.print();maa.print();
    return 0;
}
posted @ 2022-03-23 21:47  fengwu2005  阅读(57)  评论(0)    收藏  举报