NOI模拟3

考的是挺烂的,没啥可说的

犯了一些挺智障的错误吧,比如树剖没有先走重儿子,走完之后下一次遍历忘了跳过......

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=2e6+5;
const int mod=998244353;
int T,n;char a[N],b[N];
int ans;
int sol1(int x,int y,int z){
    int ret=1;
    fo(i,1,2*n+1){
        if((i&1)&&(a[i]-'A'!=x&&a[i]!='?'))return 0;
        if(((i&1)^1)&&(a[i]-'A'!=y&&a[i]!='?'))return 0;
    }
    fo(i,1,2*n+1){
        if((i&1)&&(b[i]-'A'!=z&&b[i]!='?'))return 0;
        if(((i&1)^1)){
            if(b[i]=='?')ret=ret*2%mod;
            else if(b[i]-'A'==z)return 0;
        }
    }
    return ret;
}
bool prea[N],preb[N],sufa[N],sufb[N];
int sol2(int x,int y,int z){
    fo(i,1,2*n+1)if((i&1)^1){
        if(a[i]-'A'!=z&&a[i]!='?')return 0;
        if(b[i]-'A'!=z&&b[i]!='?')return 0;
    }
    prea[0]=preb[0]=true;
    fo(i,1,2*n+1)if(i&1){
        prea[i+1>>1]=prea[i>>1]&(a[i]-'A'==x||a[i]=='?');
        preb[i+1>>1]=preb[i>>1]&(b[i]-'A'==y||b[i]=='?');
    }
    sufa[n+2]=sufb[n+2]=true;
    fu(i,2*n+1,1)if(i&1){
        sufa[i+1>>1]=sufa[i+3>>1]&(a[i]-'A'==y||a[i]=='?');
        sufb[i+1>>1]=sufb[i+3>>1]&(b[i]-'A'==x||b[i]=='?');
    }
    int ret=0;
    fo(i,1,n)if(prea[i]&preb[i]&sufa[i+1]&sufb[i+1])ret++;
    if(prea[n+1]&preb[n+1])ret--;
    return ret;
}
signed main(){
    freopen("a.in","r",stdin);
    freopen("a.out","w",stdout);
    T=read();
    while(T--){
        n=read();ans=0;
        scanf("%s%s",a+1,b+1);
        fo(i,0,2)fo(j,0,2)if(i!=j)fo(k,0,2)if(i!=k&&j!=k)ans=(ans+sol1(i,j,k))%mod;
        fo(i,1,2*n+1)swap(a[i],b[i]);
        fo(i,0,2)fo(j,0,2)if(i!=j)fo(k,0,2)if(i!=k&&j!=k)ans=(ans+sol1(i,j,k))%mod;
        fo(i,1,2*n+1)swap(a[i],b[i]);
        fo(i,0,2)fo(j,0,2)if(i!=j)fo(k,0,2)if(i!=k&&j!=k)ans=(ans+sol2(i,j,k))%mod;
        printf("%lld\n",ans);
    }
    return 0;
}

T2 铃原露露

转化为找不合法的,分两种情况,然后可以转化为矩形覆盖,通过启发式合并可以去掉绝大多数的无用矩形

最后扫描线一下就行了...

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=2e5+5;
int n,m,a[N];
struct matrix{
    int xa,ya,xb,yb;
    matrix(){}
    matrix(int a,int b,int c,int d){
        xa=a;xb=b;ya=c;yb=d;
    }
}ma[N*40];int cma;
struct E{int to,nxt;}e[N];
int head[N],rp;
void add_edg(int x,int y){e[++rp].to=y;e[rp].nxt=head[x];head[x]=rp;}
set<int> vec[N];
void dfs(int x){
    // cerr<<x<<endl;
    for(int i=head[x];i;i=e[i].nxt){
        int y=e[i].to;dfs(y);
        if(vec[x].size()<vec[y].size())swap(vec[x],vec[y]);
        for(int j:vec[y]){
            // cerr<<"SB"<<" "<<j<<endl;
            set<int>::iterator it=vec[x].lower_bound(j),pr;
            // cerr<<"ZZ"<<" "<<*it<<endl;
            if(it!=vec[x].begin())pr=prev(it);
            // cerr<<"OK"<<endl;
            // if(it==vec[x].end())cerr<<*pr<<endl;
            // cerr<<"FK"<<endl;
            if(j<x){
                // cerr<<"FI"<<endl;
                if(it!=vec[x].end()&&*it<x)ma[++cma]=matrix(1,j,*it,x-1);
                if(it!=vec[x].begin())ma[++cma]=matrix(1,*pr,j,x-1);
            }
            else {
                // cerr<<"SE"<<endl;
                if(it!=vec[x].begin()&&*pr>x)ma[++cma]=matrix(x+1,*pr,j,n);
                if(it!=vec[x].end())ma[++cma]=matrix(x+1,j,*it,n);
            }
        }
        for(int j:vec[y])vec[x].insert(j);
    }
    vec[x].insert(x);
}
struct XDS{
    #define ls x<<1
    #define rs x<<1|1
    int mn[N*4],cm[N*4],sm[N*4],tg[N*4],tj[N*4];
    void pushup(int x){
        mn[x]=min(mn[ls],mn[rs]);cm[x]=0;
        if(mn[x]==mn[ls])cm[x]+=cm[ls];
        if(mn[x]==mn[rs])cm[x]+=cm[rs];
        sm[x]=sm[ls]+sm[rs];
    }
    void pushdown(int x){
        if(tg[x]){
            tg[ls]+=tg[x];mn[ls]+=tg[x];
            tg[rs]+=tg[x];mn[rs]+=tg[x];
            tg[x]=0;
        }
        if(tj[x]){
            if(mn[ls]==mn[x]){
                tj[ls]+=tj[x];sm[ls]+=tj[x]*cm[ls];
            }
            if(mn[rs]==mn[x]){
                tj[rs]+=tj[x];sm[rs]+=tj[x]*cm[rs];
            }
            tj[x]=0;
        }
    }
    void build(int x,int l,int r){
        mn[x]=0;cm[x]=r-l+1;sm[x]=tg[x]=tj[x]=0;
        if(l==r)return ;
        int mid=l+r>>1;
        build(ls,l,mid);build(rs,mid+1,r);
    }
    void ins_tg(int x,int l,int r,int ql,int qr,int v){
        if(ql<=l&&r<=qr){
            tg[x]+=v;mn[x]+=v;
            return ;
        }
        int mid=l+r>>1;if(tg[x]||tj[x])pushdown(x);
        if(ql<=mid)ins_tg(ls,l,mid,ql,qr,v);
        if(qr>mid)ins_tg(rs,mid+1,r,ql,qr,v);
        pushup(x);
    }
    void ins_tj(int x,int l,int r,int ql,int qr){
        if(ql<=l&&r<=qr){
            if(mn[x]==0){
                tj[x]++;
                sm[x]+=cm[x];
                // cerr<<"ins_tj"<<" "<<x<<" "<<l<<" "<<r<<" "<<ql<<" "<<qr<<" "<<tj[x]<<endl;
            }
            return ;
        }
        int mid=l+r>>1;if(tg[x]||tj[x])pushdown(x);
        if(ql<=mid)ins_tj(ls,l,mid,ql,qr);
        if(qr>mid)ins_tj(rs,mid+1,r,ql,qr);
        pushup(x);
    }
    int query(int x,int l,int r,int ql,int qr){
        if(ql<=l&&r<=qr)return sm[x];
        int mid=l+r>>1,ret=0;if(tg[x]||tj[x])pushdown(x);
        if(ql<=mid)ret+=query(ls,l,mid,ql,qr);
        if(qr>mid)ret+=query(rs,mid+1,r,ql,qr);
        pushup(x);return ret;
    }
    #undef ls
    #undef rs
}xds;
vector<int> add[N],del[N],q[N];
int ll[N],rr[N],ans[N];
signed main(){
    freopen("b.in","r",stdin);
    freopen("b.out","w",stdout);
    n=read();m=read();
    fo(i,1,n)a[i]=read();
    fo(i,2,n){
        int x=read();
        add_edg(a[x],a[i]);
    }
    fo(i,1,m){
        ll[i]=read();rr[i]=read();
        q[rr[i]].push_back(i);
    }
    dfs(a[1]);xds.build(1,1,n);
    // cerr<<cma<<endl;
    fo(i,1,cma){
        // cerr<<ma[i].xa<<" "<<ma[i].xb<<" "<<ma[i].ya<<" "<<ma[i].yb<<endl;
        add[ma[i].ya].push_back(i);
        del[ma[i].yb+1].push_back(i);
    }
    fo(i,1,n){
        for(int x:add[i])xds.ins_tg(1,1,n,ma[x].xa,ma[x].xb,1);
        for(int x:del[i])xds.ins_tg(1,1,n,ma[x].xa,ma[x].xb,-1);
        xds.ins_tj(1,1,n,1,i);
        for(int x:q[i])ans[x]=xds.query(1,1,n,ll[x],rr[x]);
        // cerr<<i<<" "<<xds.query(1,1,n,2,2)<<" "<<xds.query(1,1,n,ll[1],rr[1])<<endl;
    }
    fo(i,1,m)printf("%lld\n",ans[i]);
}

T3 赫露艾斯塔

不会...

posted @ 2022-05-06 22:03  fengwu2005  阅读(37)  评论(0)    收藏  举报