省选磨泥34

可能是时运不济,导致我菜到家了...

AK啊三个人,啊啊啊我只有一半的分

一眼切第一题,第二题整个人发憷,第三题想打部分分打完了发现假了...

T1 无向图

直接可撤销线性基,据说有直接撤销版本的单\(log\),我我是线段树分治

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=1e5+5;
int m,q,ans[N];
struct BAS{
    int lba[35],cba;
    int ins(int x){
        fu(i,30,0)if(x>>i&1){
            if(lba[i])x^=lba[i];
            else {
                lba[i]=x;cba++;
                return i;
            }
        }
        return -1;
    }
    void ers(int x){if(x==-1)return ;lba[x]=0;cba--;}
}bas;
struct XDS{
    #define ls x<<1
    #define rs x<<1|1
    vector<int> vec[N*4];
    void ins(int x,int l,int r,int ql,int qr,int v){
        if(ql<=l&&r<=qr)return vec[x].push_back(v),void();
        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);
        return ;
    }
    int sta[N],top;
    void dfs(int x,int l,int r){
        // cerr<<x<<" "<<l<<" "<<r<<" "<<bas.cba<<endl;
        int s=top;
        for(int i:vec[x])sta[++top]=bas.ins(i);
        if(l==r){
            ans[l]=(1<<bas.cba);
            while(top>s)bas.ers(sta[top--]);
            return ;
        }
        int mid=l+r>>1;
        dfs(ls,l,mid);
        dfs(rs,mid+1,r);
        while(top>s)bas.ers(sta[top--]);
    }
    #undef ls
    #undef rs
}xds;
map<int,int> mp;
signed main(){
    freopen("xor.in","r",stdin);
    freopen("xor.out","w",stdout);
    m=read();q=read();
    fo(i,1,q){
        int tp=read(),x=read();
        if(tp==1)mp[x]=i;
        else xds.ins(1,1,q,mp[x],i-1,x),mp.erase(x);
    }
    for(pair<int,int> i:mp)xds.ins(1,1,q,i.second,q,i.first);
    xds.dfs(1,1,q);
    fo(i,1,q)printf("%d\n",ans[i]);
    return 0;
}

T2 加与乘

A要是最后一手,那A必胜

如果B是最后一手的话,那么当A操作时如果两个相邻的偶数之间都有奇数个奇数,包括和开头和末尾,那A必输

那么如果是A先手直接判断就好了

如果是B先手,判断是不是只有一个区间是不合法的就好了

考场上看出来这个结论了,但是没有分A先手还是B先手,其实就是不会

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=1e5+5;
int T,n[11],m[11],a[11][N];
int mx,dp[21][1<<20][2],sum[1<<20];
inline int get(int l,int r){return (1<<l+1)-(1<<r);}
void init_dp(){
    dp[1][1][0]=dp[1][1][1]=1;
    dp[1][0][0]=dp[1][0][1]=0;
    fo(len,2,20)fo(s,0,(1<<len)-1){
        fo(i,0,1){
            bool flag=i^1;
            fo(j,1,len-1){int t;
                int t1=(s>>j)&1,t2=(s>>j-1)&1;
                t=((s&get(len-1,j+1))>>1)|((t1&t2)<<j-1)|(s&get(j-2,0));
                if(dp[len-1][t][i^1]==i)flag=i;
                t=((s&get(len-1,j+1))>>1)|((t1^t2)<<j-1)|(s&get(j-2,0));
                if(dp[len-1][t][i^1]==i)flag=i;
            }
            dp[len][s][i]=flag;
        }
    }
}
void spj(int id){int now=0;
    fo(i,1,n[id])now=(now<<1)+a[id][i];
    printf(dp[n[id]][now][m[id]]?"B\n":"A\n");
}
signed main(){
    freopen("game.in","r",stdin);
    freopen("game.out","w",stdout);
    T=read();bool fl=false;
    fo(tt,1,T){
        n[tt]=read();m[tt]=read();
        fo(i,1,n[tt])a[tt][i]=read()&1;
        if(n[tt]<=20)fl=true,mx=max(mx,n[tt]);
    }
    if(fl)init_dp();
    fo(tt,1,T){
        if(((n[tt]-1)&1)!=m[tt]){printf("A\n");continue;}
        if(n[tt]<=20){spj(tt);continue;}
        int las=0,sm=0;int flag=0;
        fo(i,1,n[tt])if(!a[tt][i]){
            if(i-las&1)flag++;
            las=i;sm++;
        }
        if(n[tt]+1-las&1)flag++;
        if(!m[tt])printf(!flag?"B\n":"A\n");
        else if(m[tt])printf(flag==1?"B\n":"A\n");
    }
    return 0;
}

T3 数颜色

发现就是统计一个点被覆盖了但是他到他爹的边没有被覆盖的个数

于是我们分机器人考虑,一个机器人的贡献就是在lca处给出的

如果贡献不见了,那就是被其他的机器人路线给覆盖了

我们想要找前驱和后继,但是发现如果有两个一样的机器人,那就互相找不到了

于是我们让后面的可以找到前面的,就找前驱的时候覆盖lca,后继的时候就不覆盖了

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=1e5+5;
int n,m,q,ans[N];
struct A{int x,y,lca;}a[N];
struct B{int l,r,id;}b[N];
bool com(B a,B b){return a.l<b.l;}
struct E{int to,nxt;}e[N*2];
int head[N],rp;
void add_edg(int x,int y){e[++rp].to=y;e[rp].nxt=head[x];head[x]=rp;}
struct XDS{
    #define ls x<<1
    #define rs x<<1|1
    int who[N*4],two[N*4];
    void pushdown(int x){
        who[ls]=two[ls]=two[x];
        who[rs]=two[rs]=two[x];
        two[x]=0;return ;
    }
    void build(int x,int l,int r){
        who[x]=two[x]=0;
        if(l==r)return ;
        int mid=l+r>>1;
        build(ls,l,mid);
        build(rs,mid+1,r);
        return ;
    }
    void ins(int x,int l,int r,int ql,int qr,int v){
        if(ql>qr)return ;
        if(ql<=l&&r<=qr)return who[x]=two[x]=v,void();
        int mid=l+r>>1;if(two[x])pushdown(x);
        if(ql<=mid)ins(ls,l,mid,ql,qr,v);
        if(qr>mid)ins(rs,mid+1,r,ql,qr,v);
    }
    int query(int x,int l,int r,int pos){
        if(l==r)return who[x];
        int mid=l+r>>1;if(two[x])pushdown(x);
        if(pos<=mid)return query(ls,l,mid,pos);
        else return query(rs,mid+1,r,pos);
    }
    #undef ls
    #undef rs
}xds;
int siz[N],son[N],top[N],dep[N],fa[N];
void dfs_fi(int x,int f){
    fa[x]=f;dep[x]=dep[f]+1;
    siz[x]=1;son[x]=0;
    for(int i=head[x];i;i=e[i].nxt){
        int y=e[i].to;
        if(y==f)continue;
        dfs_fi(y,x);siz[x]+=siz[y];
        if(!son[x]||siz[y]>siz[son[x]])son[x]=y;
    }
}
int dfn[N],idf[N],cnt;
void dfs_se(int x,int f){
    top[x]=f;dfn[x]=++cnt;idf[cnt]=x;
    if(son[x])dfs_se(son[x],f);
    for(int i=head[x];i;i=e[i].nxt){
        int y=e[i].to;
        if(y==fa[x]||y==son[x])continue;
        dfs_se(y,y);
    }
}
int LCA(int x,int y){
    while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]])swap(x,y);
        x=fa[top[x]];
    }return dep[x]<dep[y]?x:y;
}
void change1(int x,int y,int v){
    while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]])swap(x,y);
        xds.ins(1,1,n,dfn[top[x]],dfn[x],v);
        x=fa[top[x]];
    }
    if(dep[x]>dep[y])swap(x,y);
    xds.ins(1,1,n,dfn[x],dfn[y],v);
}
void change2(int x,int y,int v){
    while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]])swap(x,y);
        xds.ins(1,1,n,dfn[top[x]],dfn[x],v);
        x=fa[top[x]];
    }
    if(dep[x]>dep[y])swap(x,y);
    xds.ins(1,1,n,dfn[x]+1,dfn[y],v);
}
int ll[N],rr[N];
struct BIT{
    int tr[N];
    void insert(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;
    }
    void ins(int l,int r,int v){
        // cerr<<"ins"<<" "<<l<<" "<<r<<" "<<v<<endl;
        insert(l,v);insert(r+1,-v);
    }
}bit;
vector<int> del[N];
signed main(){
    freopen("tree.in","r",stdin);
    freopen("tree.out","w",stdout);
    n=read();m=read();q=read();
    fo(i,1,n-1){
        int x=read(),y=read();
        add_edg(x,y);add_edg(y,x);
    }
    dfs_fi(1,0);dfs_se(1,1);
    fo(i,1,m)a[i].x=read(),a[i].y=read(),a[i].lca=LCA(a[i].x,a[i].y);
    fo(i,1,q)b[i].l=read(),b[i].r=read(),b[i].id=i;
    fo(i,1,m){
        ll[i]=xds.query(1,1,n,dfn[a[i].lca]);
        change1(a[i].x,a[i].y,i);
    }xds.build(1,1,n);
    fu(i,m,1){
        rr[i]=xds.query(1,1,n,dfn[a[i].lca]);
        change2(a[i].x,a[i].y,i);
    }
    sort(b+1,b+q+1,com);b[q+1].l=m+1;
    // fo(i,1,m)cerr<<ll[i]<<" "<<rr[i]<<endl;
    fu(qq,q,1){
        fu(i,b[qq+1].l-1,b[qq].l){
            // cerr<<qq<<" "<<i<<" "<<b[qq].l<<endl;
            for(int x:del[i]){
                if(rr[x])bit.ins(x,rr[x]-1,-1);
                else bit.ins(x,n,-1);
            }
            if(rr[i])bit.ins(i,rr[i]-1,1);
            else bit.ins(i,n,1);
            if(ll[i])del[ll[i]].push_back(i);
        }
        // cerr<<"ans"<<" "<<b[qq].id<<" "<<b[qq].l<<" "<<b[qq].r<<" "<<bit.query(b[qq].r)<<endl;
        ans[b[qq].id]=bit.query(b[qq].r);
    }
    fo(i,1,q)printf("%d\n",ans[i]);
}
posted @ 2022-03-18 19:10  fengwu2005  阅读(57)  评论(0编辑  收藏  举报