省选模拟(20220309)

好像是之前数据结构专题没考完的题...

本来之前认为数据结构是强项,认为自己码力还是挺强的,然而现在发现根本不是码力的问题,而是想不到的问题!!

开场看T1,想到对于每个墙分治,然而没法去重啊,后来知道了可以按照括号匹配去重

T2看上去有点眼熟,后来发现要记录历史版本,然而我又不会了,答案记录的时候永久化

T3是真的不会了,现在还没有改完,似乎被卡常数了......

T1 鱼死网破

我们能想到的是,每个士兵按照墙做差分!!

查询的时候按照墙二分就行了!!

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*10+ch-'0';ch=getchar();}
    return s*t;
}
const int N=1e5+5;
struct VEC{
    double x,y;double arg;int val,id;
    VEC(){}VEC(double a,double b,int v,int i){x=a;y=b;arg=atan2(y,x);val=v;id=i;}
    bool operator < (VEC a)const{
        return arg<a.arg;
    }
    bool operator == (VEC a)const{
        return arg==a.arg;
    }
}p[105][N],sod[N],tmp[N];
int n,k,m,ans,op,a[55],b[55],c[55];
int sta[N],top,cp[105],pre[105][N];
signed main(){
    freopen("clash.in","r",stdin);
    freopen("clash.out","w",stdout);
    n=read();k=read();m=read();op=read();
    fo(i,1,n){
        int x=read(),y=read();
        sod[i]=VEC(x,y,0,0);
    }
    fo(i,1,k){a[i]=read();b[i]=read();c[i]=read();}
    fo(i,1,n){int cnt=0;
        fo(j,1,k){
            if(c[j]>=sod[i].y)continue;
            tmp[++cnt]=VEC(a[j]-sod[i].x,c[j]-sod[i].y,1,j*2-1);
            tmp[++cnt]=VEC(b[j]-sod[i].x,c[j]-sod[i].y,-1,j*2);
        }
        sort(tmp+1,tmp+cnt+1);
        // if(i==5){cerr<<"SB"<<endl;fo(j,1,cnt)cerr<<tmp[j].id<<" ";cerr<<endl;}
        // cerr<<"SB"<<" "<<cnt<<endl;
        fo(j,1,cnt){
            if(tmp[j].val==-1){
                // if(i==5)cerr<<j<<" "<<top<<" "<<tmp[j].id<<endl;
                if(top==1){
                    // if(tmp[j].id==1)cerr<<i<<endl;
                    p[tmp[j].id][++cp[tmp[j].id]]=tmp[j];
                    // if(tmp[sta[top]].id==1)cerr<<i<<endl;
                    p[tmp[sta[top]].id][++cp[tmp[sta[top]].id]]=tmp[sta[top]];
                }
                top--;
            }
            else sta[++top]=j;
        }
    }
    fo(i,1,k){
        sort(p[i*2-1]+1,p[i*2-1]+cp[i*2-1]+1);
        fo(j,1,cp[i*2-1])pre[i*2-1][j]=pre[i*2-1][j-1]+p[i*2-1][j].val;
        sort(p[i*2]+1,p[i*2]+cp[i*2]+1);
        fo(j,1,cp[i*2])pre[i*2][j]=pre[i*2][j-1]+p[i*2][j].val;
    }
    // cerr<<cp[1]<<endl;
    while(m--){
        int x=(read()^ans*op),y=(read()^ans*op);ans=0;
        fo(i,1,k){VEC now=VEC(x-a[i],y-c[i],0,0);
            int pos=upper_bound(p[i*2-1]+1,p[i*2-1]+cp[i*2-1]+1,now)-p[i*2-1]-1;
            // cerr<<pos<<" "<<p[i*2-1][pos].val<<endl;
            if(p[i*2-1][pos]==now&&p[i*2-1][pos].val==-1)pos--;
            ans+=pre[i*2-1][pos];
            // cerr<<i*2-1<<" "<<pos<<" "<<pre[i*2-1][pos]<<" "<<(p[i*2-1][pos+1].arg==now.arg)<<endl;
            now=VEC(x-b[i],y-c[i],0,0);
            pos=upper_bound(p[i*2]+1,p[i*2]+cp[i*2]+1,now)-p[i*2]-1;
            if(p[i*2][pos]==now&&p[i*2][pos].val==-1)pos--;
            ans+=pre[i*2][pos];
            // cerr<<i*2<<" "<<pos<<" "<<pre[i*2][pos]<<endl;
        }
        printf("%d\n",ans=n-ans);

    }
    return 0;
}

T2 漏网之鱼

尤其是pushdown的时候,如果下面的都相等,那就标记永久化就行了

AC_code
#include<bits/stdc++.h>
using namespace std;
#define ull 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<<3)+(s<<1)+(ch^48);ch=getchar();}
    return s*t;
}
const int N=1e6+5;
int n,a[N],mex[N];
struct XDS{
    #define ls x<<1
    #define rs x<<1|1
    int mx[N*4],mn[N*4],tg[N*4];
    ull sm[N*4],ans[N*4],hs[N*4],ts[N*4];
    inline void pushup(int x,int l,int r){
        mx[x]=max(mx[ls],mx[rs]);
        mn[x]=min(mn[ls],mn[rs]);
        sm[x]=sm[ls]+sm[rs];
        ans[x]=ans[ls]+ans[rs]+hs[x]*(r-l+1);
        return ;
    }
    inline void pushdown(int x,int l,int r){
        int mid=l+r>>1;
        if(ts[x]){
            if(mn[ls]==mx[ls])hs[ls]+=1ull*mx[ls]*ts[x];
            else ts[ls]+=ts[x];
            ans[ls]+=1ull*sm[ls]*ts[x];
            if(mn[rs]==mx[rs])hs[rs]+=1ull*mx[rs]*ts[x];
            else ts[rs]+=ts[x];
            ans[rs]+=1ull*sm[rs]*ts[x];ts[x]=0;
        }
        if(tg[x]){
            mx[ls]=mn[ls]=tg[ls]=tg[x];
            sm[ls]=1ull*tg[x]*(mid-l+1);
            mx[rs]=mn[rs]=tg[rs]=tg[x];
            sm[rs]=1ull*tg[x]*(r-mid);tg[x]=0;
        }return ;
    }
    void build(int x,int l,int r){
        if(l==r){
            mx[x]=mn[x]=mex[l];
            sm[x]=mex[l];
            ans[x]=mex[l];
            return ;
        }
        int mid=l+r>>1;
        build(ls,l,mid);build(rs,mid+1,r);
        pushup(x,l,r);return ;
    }
    void ins_ts(int x,int l,int r,int ql,int qr){
        if(ql<=l&&r<=qr){
            if(mn[x]==mx[x])hs[x]+=mx[x];
            else ts[x]++;
            ans[x]+=sm[x];
            return ;
        }
        int mid=l+r>>1;if(tg[x]||ts[x])pushdown(x,l,r);
        if(ql<=mid)ins_ts(ls,l,mid,ql,qr);
        if(qr>mid)ins_ts(rs,mid+1,r,ql,qr);
        pushup(x,l,r);return ;
    }
    ull query(int x,int l,int r,int ql,int qr){
        if(ql>qr)return 0;
        if(ql<=l&&r<=qr)return ans[x];
        int mid=l+r>>1;ull ret=0;if(tg[x]||ts[x])pushdown(x,l,r);
        if(ql<=mid)ret+=query(ls,l,mid,ql,qr);
        if(qr>mid)ret+=query(rs,mid+1,r,ql,qr);
        ret+=hs[x]*(min(qr,r)-max(ql,l)+1);
        pushup(x,l,r);return ret;
    }
    void que(int x,int l,int r,int ql,int qr,int v){
        if(ql>qr)return ;
        if(ql<=l&&r<=qr){
            if(mn[x]>v){
                mx[x]=mn[x]=v;
                sm[x]=1ull*v*(r-l+1);
                tg[x]=v;
                return ;
            }
            if(l==r)return ;
            int mid=l+r>>1;if(tg[x]||ts[x])pushdown(x,l,r);
            if(mx[rs]>v)que(rs,mid+1,r,ql,qr,v);
            if(mx[ls]>v)que(ls,l,mid,ql,qr,v);
            pushup(x,l,r);return ;
        }
        int mid=l+r>>1;if(tg[x]||ts[x])pushdown(x,l,r);
        if(ql<=mid)que(ls,l,mid,ql,qr,v);
        if(qr>mid)que(rs,mid+1,r,ql,qr,v);
        pushup(x,l,r);return ;
    }
    #undef ls
    #undef rs
}xds;
ull ans[N];
int Q,ll[N],rr[N],nxt[N],buc[N];
vector<int> sum[N],dc[N]; 
signed main(){
    freopen("escape.in","r",stdin);
    freopen("escape.out","w",stdout);
    int sb=read();
    n=read();mex[0]=1;
    fo(i,1,n)a[i]=read()+1;
    fo(i,1,n){
        mex[i]=mex[i-1];nxt[i]=n+1;
        if(a[i]<=n)nxt[buc[a[i]]]=i,buc[a[i]]=i;
        else nxt[i]=0;
        while(buc[mex[i]])mex[i]++;
    }
    xds.build(1,1,n);
    Q=read();
    fo(i,1,Q){
        ll[i]=read();rr[i]=read();
        ans[i]-=1ull*(rr[i]-ll[i]+1)*(rr[i]-ll[i]+2)/2;
        dc[ll[i]-1].push_back(i);
        sum[rr[i]].push_back(i);
    }
    fo(i,1,n){
        for(int j:dc[i])ans[j]-=xds.query(1,1,n,ll[j],rr[j]);
        for(int j:sum[i])ans[j]+=xds.query(1,1,n,ll[j],rr[j]);
        if(i==n)continue;
        xds.que(1,1,n,i+1,nxt[i]-1,a[i]);
        xds.ins_ts(1,1,n,i+1,n);
        // if(1.0*clock()/CLOCKS_PER_SEC>=3.99)cerr<<i<<endl;
    }
    fo(i,1,Q)printf("%lld\n",ans[i]);
    return 0;
}

T3 浑水摸鱼

hash值,记录现在和前面第一个相同的数的距离,直接后缀排序,找lcp找不同就完事了

TLE_code
#include<bits/stdc++.h>
using namespace std;
#define ull 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*10+ch-'0';ch=getchar();}
    return s*t;
}
const int N=5e4+5;
const ull bas=131;
ull ba[N];int n,nxt[N],pre[N];
struct ZXS{
    struct POT{int ls,rs;ull sum;}tr[N*30];
    int seg,rt[N];
    void insert(int &x,int px,int l,int r,int pos,ull v){
        if(!pos||pos>r)return ;
        x=++seg;tr[x]=tr[px];
        if(l==r)return tr[x].sum+=v,void();
        int mid=l+r>>1;
        if(pos<=mid)insert(tr[x].ls,tr[px].ls,l,mid,pos,v);
        else insert(tr[x].rs,tr[px].rs,mid+1,r,pos,v);
        tr[x].sum=tr[tr[x].ls].sum*ba[r-mid]+tr[tr[x].rs].sum;
        return ;
    }
    inline void ins(int x){
        if(!nxt[x]){rt[x]=rt[x-1];return ;}
        insert(rt[x],rt[x-1],1,n,nxt[x],nxt[x]-x);
    }
    ull query(int x,int y,int l,int r,int ql,int qr){
        if(ql>qr||!x)return 0;
        if(ql<=l&&r<=qr)return tr[x].sum-tr[y].sum;
        int mid=l+r>>1;ull ret=0;
        if(ql<=mid)ret=query(tr[x].ls,tr[y].ls,l,mid,ql,qr);
        if(qr>mid)ret=ret*ba[min(qr,r)-mid]+query(tr[x].rs,tr[y].rs,mid+1,r,ql,qr);
        tr[x].sum=tr[tr[x].ls].sum*ba[r-mid]+tr[tr[x].rs].sum;
        return ret;
    }
    inline ull qry(int l,int r){return query(rt[r],rt[l-1],1,n,l,r);}
}zxs;
int cnt=0;
inline bool com(int x,int y){cnt++;
    int l=0,r=min(n-x+1,n-y+1),mid;
    while(l<r){
        mid=l+r+1>>1;
        if(zxs.qry(x,x+mid-1)==zxs.qry(y,y+mid-1))l=mid;
        else r=mid-1;
    }
    if(l==n-x+1)return true;
    if(l==n-y+1)return false;
    return (pre[x+l]>=x?x+l-pre[x+l]:0)<(pre[y+l]>=y?y+l-pre[y+l]:0);
}
int xl[N],buc[N],a[N];
ull ans;
signed main(){
    freopen("waterflow.in","r",stdin);
    freopen("waterflow.out","w",stdout);
    n=read();
    fo(i,1,n){
        a[i]=read();
        pre[i]=buc[a[i]];
        nxt[buc[a[i]]]=i;
        buc[a[i]]=i;
    }
    ba[0]=1;fo(i,1,n)ba[i]=ba[i-1]*bas;
    fo(i,1,n)zxs.ins(i),xl[i]=i;
    stable_sort(xl+1,xl+n+1,com);
    // cerr<<cnt<<endl;
    ans=n-xl[1]+1;
    fo(i,2,n){
        int l=0,r=min(n-xl[i-1]+1,n-xl[i]+1),mid;
        while(l<r){
            mid=l+r+1>>1;
            if(zxs.qry(xl[i],xl[i]+mid-1)==zxs.qry(xl[i-1],xl[i-1]+mid-1))l=mid;
            else r=mid-1;
        }
        ans+=n-xl[i]+1-l;
    }
    printf("%llu",ans);
}
posted @ 2022-03-10 08:33  fengwu2005  阅读(44)  评论(0编辑  收藏  举报