省选模拟40

没啥感觉,对面的niuma又切了两道题...

T1 交通

似乎是个垃圾题,可以直接线段树,不知为何数据范围这么小

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=5e4+5;
const int inf=0x3f3f3f3f3f3f3f3f;
const int R=2e9;
struct XDS{
    struct POT{
        int mn,ls,rs;
        POT(){mn=inf;}
    }tr[N*35];
    int seg,rt;
    int newpot(){
        ++seg;
        tr[seg].ls=tr[seg].rs=0;
        tr[seg].mn=inf;
        return seg;
    }
    void clear(){seg=0;}
    void pushup(int x){
        tr[x].mn=min(tr[tr[x].ls].mn,tr[tr[x].rs].mn);
        return ;
    }
    void ins(int &x,int l,int r,int pos,int v){
        if(!x)x=newpot();
        if(l==r)return tr[x].mn=v,void();
        int mid=l+r>>1;
        if(pos<=mid)ins(tr[x].ls,l,mid,pos,v);
        else ins(tr[x].rs,mid+1,r,pos,v);
        pushup(x);return ;
    }
    int query(int x,int l,int r,int ql,int qr){
        if(!x)return inf;
        if(ql<=l&&r<=qr)return tr[x].mn;
        int mid=l+r>>1,ret=inf;
        if(ql<=mid)ret=min(ret,query(tr[x].ls,l,mid,ql,qr));
        if(qr>mid)ret=min(ret,query(tr[x].rs,mid+1,r,ql,qr));
        pushup(x);return ret;
    }
}xds;
int n,q,g,r,s,d[N],pd[N];
map<int,int> mp;
int beh[N],nxt[N],f[N];
bool vs[N];
signed main(){
    freopen("traffic.in","r",stdin);
    freopen("traffic.out","w",stdout);
    // cerr<<(sizeof(xds)>>20)<<endl;
    n=read();g=read();r=read();s=g+r;
    fo(i,1,n+1)d[i]=read();
    fo(i,1,n+1){
        pd[i]=pd[i-1]+d[i];
        beh[i]=inf;
        int np=pd[i]%s;
        if(mp[np])beh[mp[np]]=i;
        else xds.ins(xds.rt,0,s,np,i),vs[i]=true;
        mp[np]=i;
    }
    fo(i,1,n+1){
        int np=pd[i-1]%s;
        int l=(g+np+s)%s,r=(s-1+np+s)%s,res;
        // cerr<<l<<" "<<r<<endl;
        if(l<=r)res=xds.query(xds.rt,0,s,l,r);
        else res=min(xds.query(xds.rt,0,s,l,s),xds.query(xds.rt,0,s,0,r));
        // cerr<<"RES"<<" "<<res<<endl;
        if(res==inf)nxt[i-1]=n+1;
        else nxt[i-1]=res;
        xds.ins(xds.rt,0,s,pd[i]%s,beh[i]);
    }
    fu(i,n,0){
        if(nxt[i]==n+1)f[i]=pd[n+1]-pd[i];
        else f[i]=f[nxt[i]]+((pd[nxt[i]]-pd[i]-1)/s+1)*s;
    }
    // cerr<<pd[1]<<endl;
    // fo(i,1,n+1)cerr<<pd[i]<<" ";cerr<<endl;
    // fo(i,0,n)cerr<<nxt[i]<<" ";cerr<<endl;
    // fo(i,0,n)cerr<<f[i]<<" ";cerr<<endl;
    // cerr<<xds.seg<<" "<<N*35<<endl;
    xds.clear();
    fo(i,1,n+1)if(vs[i])xds.ins(xds.rt,0,s,pd[i]%s,i);
    q=read();
    while(q--){
        int t=read(),ans;
        int l=(g-t%s+s)%s,r=(s-1-t%s+s)%s,res;
        // cerr<<l<<" "<<r<<" ";
        if(l<=r)res=xds.query(xds.rt,0,s,l,r);
        else res=min(xds.query(xds.rt,0,s,l,s),xds.query(xds.rt,0,s,0,r));
        // cerr<<"res"<<" "<<res<<endl;
        if(res==inf||res==n+1)ans=pd[n+1]+t;
        else ans=f[res]+(t+pd[res]+(s-(pd[res]+t)%s)%s);
        // cerr<<f[res]<<" "<<t<<" "<<pd[res]<<" "<<s<<" "<<endl;
        printf("%lld\n",ans);
    }
    return 0;
}

T2 选拔

不明白一个字符串的题让他硬生生的干成了dp...神仙...

所以树形dp即可,bitset优化就完了

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--)
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=30005;
int n,m,l[N],r[N];char s[N];
struct E{int to,nxt,c;}e[N*2];
int head[N],rp;
void add_edg(int x,int y,int z){
    e[++rp].to=y;e[rp].nxt=head[x];
    e[rp].c=z;head[x]=rp;
}
bitset<N> f[N],g[N],zy[26],fb,gb,lf,lg,ans,rf,rg;
int sta[N],top;
void dfs(int x,int fa){
    sta[++top]=x;
    for(int i=head[x];i;i=e[i].nxt){
        int y=e[i].to;
        if(y==fa)continue;
        dfs(y,x);
    }
}
signed main(){
    freopen("selection.in","r",stdin);
    freopen("selection.out","w",stdout);
    n=read();
    fo(i,1,n-1){
        int x=read(),y=read();
        char c[10];scanf("%s",c+1);
        add_edg(x,y,c[1]-'a');
        add_edg(y,x,c[1]-'a');
    }
    m=read();
    lf.set();lf.reset(0);
    fo(i,1,m){
        scanf("%s",s+r[i-1]+1);
        l[i]=r[i-1]+1;
        r[i]=l[i]+strlen(s+r[i-1]+1)-1;
        fb.set(l[i]-1);rf.set(r[i]);
        lf.reset(r[i]);
        gb.set(r[i]+1);rg.set(l[i]);
    }
    fo(i,1,r[m])zy[s[i]-'a'].set(i);
    dfs(1,0);
    fu(i,top,1){
        int x=sta[i];
        for(int i=head[x];i;i=e[i].nxt){
            int y=e[i].to;
            bitset<N> tf,tg;
            tf=(((zy[e[i].c]>>1)&f[y])<<1);
            tg=(((zy[e[i].c]<<1)&g[y])>>1);
            ans|=((f[x]&lf)<<1)&tg;
            ans|=((tf&lf)<<1)&g[x];
            f[x]|=tf;g[x]|=tg;
        }
        ans|=f[x]&rf;
        ans|=g[x]&rg;
        f[x]|=fb;g[x]|=gb;
    }
    fo(i,1,m){
        bool fl=false;
        fo(j,l[i],r[i])if(ans[j])fl=true;
        if(fl)printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}

T3 等待

讲题听了5分钟后一直处于离线状态...

题解一个字看不进去...

meiyou_code

posted @ 2022-03-29 20:56  fengwu2005  阅读(51)  评论(0编辑  收藏  举报