[Test summary] Tham de basic resume training series

1.12

fAKe restore basic skills training

(I'm from the future: Anyway, the topic than 1.15 to harder)


T1 Mr. toluene roll list

Topic Link

Balanced tree board questions, to maintain two elements

Balanced tree board link (comment in great detail)

Paste codes (Splay):

#include <bits/stdc++.h>
#define N (1000000+5)
#define DEBUG puts("!!!");
using namespace std;
typedef unsigned int ui;
ui randNum(ui &seed, ui last,const ui m){
    seed=seed*17+last;
    return seed%m+1;
}
ui m,sd,lst=7;
int t,n;
int rt,tot,fa[N],cnt[N],ch[N][2],vala[N],valb[N],siz[N];
int nowa[N],nowb[N];
inline void maintain(int x){
    siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+cnt[x];
}
inline bool get(int x){
    return x==ch[fa[x]][1];
}
inline void clear(int x){
    ch[x][0]=ch[x][1]=fa[x]=cnt[x]=vala[x]=valb[x]=siz[x]=0;
}
inline void rotate(int x){
    int y=fa[x],z=fa[y],k=get(x);
    ch[y][k]=ch[x][k^1];
    fa[ch[x][k^1]]=y;
    ch[x][k^1]=y;
    fa[y]=x;
    fa[x]=z;
    if(z) ch[z][y==ch[z][1]]=x;
    maintain(y),maintain(x);
}
inline void splay(int x,int g=0){
    while(fa[x]!=g){
        int f=fa[x],ff=fa[f];
        if(ff!=g) get(x)==get(f)?rotate(f):rotate(x);
        rotate(x);
    }
    if(!g) rt=x;
}
inline void insert(int a,int b){
    if(!rt){
        vala[++tot]=a,valb[tot]=b;
        rt=tot,cnt[tot]++;
        maintain(rt);
        return;
    }
    int cnr=rt,f=0;
    while(1){
        if(vala[cnr]==a&&valb[cnr]==b){
            cnt[cnr]++;
            maintain(cnr);
            splay(cnr);
            break;
        }
        f=cnr;
        if(a<vala[cnr]||(a==vala[cnr]&&b>valb[cnr])) cnr=ch[cnr][1];
        else cnr=ch[cnr][0];
        if(!cnr){
            vala[++tot]=a,valb[tot]=b;
            cnt[tot]++;
            fa[tot]=f,ch[f][a<vala[f]||(a==vala[f]&&b>valb[f])]=tot;
            maintain(f),maintain(tot);
            splay(tot);
            break;
        }
    }
}
inline int rk(int a,int b){
    int res=0,cnr=rt;
    while(1){
        if(a>vala[cnr]||(a==vala[cnr]&&b<valb[cnr])) cnr=ch[cnr][0];
        else{
            res+=siz[ch[cnr][0]];
            if(a==vala[cnr]&&b==valb[cnr]){
                splay(cnr);
                return res+1;
            }
            res+=cnt[cnr];
            cnr=ch[cnr][1];
        }
    }
}
inline int pre(){
    int cnr=ch[rt][0];
    while(ch[cnr][1]) cnr=ch[cnr][1];
    return cnr;
}
inline void del(int a,int b){
    rk(a,b);
    if(cnt[rt]>1){
        cnt[rt]--,maintain(rt);
        return;
    }
    if(!ch[rt][0]&&!ch[rt][1]){
        clear(rt),rt=0;
        return;
    }
    if(!ch[rt][0]){
        int cnr=rt;
        rt=ch[cnr][1];
        fa[rt]=0;
        clear(cnr);
        return;
    }
    if(!ch[rt][1]){
        int cnr=rt;
        rt=ch[cnr][0];
        fa[rt]=0;
        clear(cnr);
        return;
    }
    int x=pre(),cnr=rt;
    splay(x);
    fa[ch[cnr][1]]=x;
    ch[x][1]=ch[cnr][1];
    clear(cnr);
    maintain(rt);
}
int main(){
    scanf("%d",&t);
    while(t--){
        scanf("%d%d%d",&m,&n,&sd);
        memset(nowa,0,sizeof(nowa));//过于 chou lou
        memset(nowb,0,sizeof(nowb));
        memset(fa,0,sizeof(fa));
        memset(ch,0,sizeof(ch));
        memset(cnt,0,sizeof(cnt));
        memset(vala,0,sizeof(vala));
        memset(valb,0,sizeof(valb));
        memset(siz,0,sizeof(siz));
        rt=0,tot=0;
        while(n--){
            ui ria=randNum(sd,lst,m);
            ui rib=randNum(sd,lst,m);
            if(nowa[ria]) del(nowa[ria],nowb[ria]);
            nowa[ria]++,nowb[ria]+=rib;
            insert(nowa[ria],nowb[ria]);
            lst=rk(nowa[ria],nowb[ria])-1;
            printf("%d\n",lst);
        }
    }
    return 0;
}

T2 counting arrangement

Topic Link

emmm I did not write too dishes

Mainly derive the number of combinations, details of problem solution Luo Valley Look, I have time to fix. . .

Solution to a problem link


And more than the number of T3

Topic Link

Divisible block template title

\ (Ans = \ sigma_ {i = 1} ^ {n} {k% i} \)

又∵ \(a%b = a - b \times \lfloor {\frac{a}{b}} \rfloor\)

\(ans = \sigma_{i=1}^{n}{k-i \times \lfloor {\frac{k}{i}} \rfloor} = n \times k - \sigma_{i=1}^{n}{i \times \lfloor {\frac{k}{i}} \rfloor}\)

Then divisible block operation \ (\ lfloor {\ frac { k} {i}} \ rfloor \)

Paste code:

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
LL n,k,ans;
int main(){
    scanf("%lld%lld",&n,&k);
    ans=n*k;
    for(LL l=1,r=0;l<=n;l=r+1){
        LL t=k/l;
        if(t){
            r=min(k/t,n);
        }
        else r=n;
        ans-=t*(r-l+1)*(l+r)>>1;
    }
    printf("%lld",ans);
    return 0;
}

1.15

~ Really restore basic skills training

Today's emergent topics, the questions are all board


T1 bird snacks

Topic Link

(SBT) Shortest board problem, the queue using Dijkstra, its height limit point not to join

Sure enough, is to restore basic skills training, engage in two months of culture, I do not even remember Dijkstra wrote (I guess I was the first to open Djkstra inside the heap into large root heap)

Paste code:

#include <bits/stdc++.h>
#define N (200000+5)
#define int long long
using namespace std;
typedef pair<int,int> paii;
int n,m,s,t,g,x;
int h[N],lim[N],dis[N],vis[N];
vector<intnanyixie> edge[N],w[N];
void add(int u,int v,int wei){
    edge[u].push_back(v);
    w[u].push_back(wei);
    edge[v].push_back(u);
    w[v].push_back(wei);
}
void dijkstra(){
    priority_queue <paii,vector<paii>,greater<paii> > q;//呜呜呜~~~
    dis[s]=0;
    int u=s;
    q.push(make_pair(0,s));
    while(!q.empty()){
        u=q.top().second;q.pop();
        vis[u]=1;
        for(int i=0;i<edge[u].size();i++){
            int now=edge[u][i];
            if(dis[now]>dis[u]+w[u][i]){
                dis[now]=dis[u]+w[u][i];
                if(!vis[now]&&(dis[now]*x+h[now]<=lim[now])){//高度超限的不加入堆
                    q.push(make_pair(dis[now],now));
                }
            }
        }
    }
}
signed main(){
    freopen("oyatsu.in","r",stdin);//留着防抄
    freopen("oyatsu.out","w",stdout);
    scanf("%lld%lld%lld%lld%lld%lld",&n,&m,&s,&t,&g,&x);
    for(int i=1;i<=n;i++){
        scanf("%lld%lld",&h[i],&lim[i]);
    }
    memset(dis,0x3f,sizeof(dis));
    for(int i=1;i<=m;i++){
        int u,v,wei;
        scanf("%lld%lld%lld",&u,&v,&wei);
        add(u,v,wei);
    }
    dijkstra();
    if(dis[t]<=g) printf("%lld",dis[t]);
    else puts("wtnap wa kotori no oyatsu desu!");
    return 0;
}

T2 leader of the magic

Topic Link

Block board problem, only yesterday I wrote

Jump Links

On the code, do not explain, and explain the point to look at the link above

#include <bits/stdc++.h>
#define N (1000000+5)
using namespace std;
int n,q,k,bl,a[N],pos[N],lazy[N],L[N],R[N];
vector <int> v[N];
void Update(int x){
    v[x].clear();
    for(int i=L[x];i<=R[x];i++){
        v[x].push_back(a[i]);
    }
    sort(v[x].begin(),v[x].end());
}
void add(int l,int r,int c){
    for(int i=l;i<=min(R[pos[l]],r);i++){
        a[i]+=c;
    }
    Update(pos[l]);
    if(pos[l]!=pos[r]){
        for(int i=L[pos[r]];i<=r;i++){
            a[i]+=c;
        }
        Update(pos[r]);
    }
    for(int i=pos[l]+1;i<pos[r];i++) lazy[i]+=c;
}
int query(int l,int r,int c){
    int x=0;
    for(int i=l;i<=min(R[pos[l]],r);i++){
        int sum=lazy[pos[l]]+a[i];
        if(sum<c) x++;
    }
    if(pos[l]!=pos[r]){
        for(int i=L[pos[r]];i<=r;i++){
            int sum=lazy[pos[l]]+a[i];
            if(sum<c) x++;
        }
    }
    for(int i=pos[l]+1;i<pos[r];i++){
        int t=c-lazy[i];
        x+=lower_bound(v[i].begin(),v[i].end(),t)-v[i].begin();
    }
    return x;
}
int main(){
    freopen("magic.in","r",stdin);//防抄
    freopen("magic.out","w",stdout);
    scanf("%d%d",&n,&q);
    k=sqrt(n),bl=n/k+(n%k!=0);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        pos[i]=(i-1)/k+1;
        v[pos[i]].push_back(a[i]);
    }
    for(int i=1;i<=bl;i++){
        L[i]=(i-1)*k+1,R[i]=i*k;
        sort(v[i].begin(),v[i].end());
    }
    R[bl]=n;
    for(int i=1;i<=q;i++){
        char opt;
        int l,r,c;
        scanf("%s",&opt);
        scanf("%d%d%d",&l,&r,&c);
        if(opt=='M') add(l,r,c);
        else if(opt=='A') printf("%d\n",r-l+1-query(l,r,c));
    }
    return 0;
}

T3 sum

Topic Link

LCA title board, pre-k to the power of every number, and add a prefix to ensure \ (O (1) \) Inquiry

The other is not difficult

估计我又是第一个把\(log_2 n\)写成\(log n\)的数学“带师”

果然我的基本功还不够扎实,不过看起来比可爱的Enterprise小姐姐好,反正都是爆零嘛~

贴一个代码,不解释了

#include <bits/stdc++.h>
#define N (300000+50)
using namespace std;
typedef long long LL;
const int mod=998244353;
int n,m,rt=1;
LL f[N][55],sum[55][N],ans;
int depth[N],fa[N][30],lgn;
vector<int> edge[N];
void add(int u,int v){
    edge[u].push_back(v);
    edge[v].push_back(u);
}
void dfs(int u,int father){
    for(int i=0;i<edge[u].size();i++){
        int now=edge[u][i];
        if(now==father) continue;
        else depth[now]=depth[u]+1,fa[now][0]=u;
        dfs(now,u);
    }
}
void getfather(){
    for(int j=1;j<=lgn;j++){
        for(int i=1;i<=n;i++){
            fa[i][j]=fa[fa[i][j-1]][j-1];
        }
    }
}
int LCA(int u,int v){
    if(depth[u]<depth[v]) swap(u,v);
    int dist=depth[u]-depth[v];
    for(int j=0;j<=lgn;j++){
        if((1<<j)&dist) u=fa[u][j];
    }
    if(u==v) return u;
    for(int j=lgn;j>=0;j--){
        if(fa[u][j]!=fa[v][j]){
            u=fa[u][j];
            v=fa[v][j];
        }
    }
    return fa[u][0];
}
void init(){
    for(int i=1;i<=300005;i++){
        for(int j=0;j<=50;j++){
            if(j==0) f[i][j]=1;
            else f[i][j]=f[i][j-1]%mod*i%mod;
        }
    }
    for(int i=1;i<=50;i++){
        for(int j=0;j<=300005;j++){
            sum[i][j]=(sum[i][j-1]+f[j][i])%mod;
        }
    }
}
int main(){
    freopen("sum.in","r",stdin);
    freopen("sum.out","w",stdout);
    init();
    scanf("%d",&n);
    lgn=log2(n);
    for(int i=1;i<n;i++){
        int u,v;
        scanf("%d%d",&u,&v);
        add(u,v);
    }
    dfs(rt,0);
    getfather();
    scanf("%d",&m);
    for(int i=1;i<=m;i++){
        int u,v,k;
        scanf("%d%d%d",&u,&v,&k);
        int lca=LCA(u,v);
        int du=depth[u],dv=depth[v],dl=depth[lca];
        if(lca==u){
            printf("%lld\n",(sum[k][dv]-sum[k][du-1]+mod)%mod);
        }
        else if(lca==v){
            printf("%lld\n",(sum[k][du]-sum[k][dv-1]+mod)%mod);
        }
        else printf("%lld\n",((sum[k][du]-sum[k][dl-1]+mod)%mod+(sum[k][dv]-sum[k][dl-1]+mod)%mod-f[dl][k]+mod)%mod);
    }
    return 0;
}

总结

看来还要多多训练才行啊

Guess you like

Origin www.cnblogs.com/Xx-queue/p/12198479.html