分块1

c8eeb9bc686542ed9dcbacd07d563aeb
//P4168
#include <bits/stdc++.h>
using namespace std;
int n,m,T,a[40010],b[40010],s[210][40010],f[210][210],t[40010];
int get_block(int u){
    return (u-1)/T+1;
}
int main(){
    ios::sync_with_stdio(0);
    cin>>n>>m;
    T=int(sqrt(n));
    for(int i=1;i<=n;i++){
        cin>>a[i];
        b[i]=a[i];
    }
    sort(b+1,b+1+n);
    int sum=unique(b+1,b+1+n)-b-1,cnt=(n-1)/T+1;
    for(int i=1;i<=n;i++){
        a[i]=lower_bound(b+1,b+1+sum,a[i])-b;
    }
    for(int i=1;i<=cnt;i++){
        for(int j=T*(i-1)+1;j<=min(T*i,n);j++){
            s[i][a[j]]++;
        }
        for(int j=1;j<=sum;j++){
            s[i][j]+=s[i-1][j];
        }
    }
    for(int i=1;i<=cnt;i++){
        for (int j=i;j<=cnt;j++){
            int mx=f[i][j-1];
            for(int k=T*(j-1)+1;k<=min(T*j,n);k++){
                if((s[j][a[k]]-s[i-1][a[k]]>s[j][mx]-s[i-1][mx])||
                (s[j][a[k]]-s[i-1][a[k]]==s[j][mx]-s[i-1][mx]&&a[k]<mx))
                    mx=a[k];
            }
            f[i][j]=mx;
        }
    }    
    int x=0;
    while(m--){
        int l,r;
        cin>>l>>r;
        l=(l+x-1)%n+1,r=(r+x-1)%n+1;
        if(l>r){
            swap(l, r);
        }
        int bl=get_block(l),br=get_block(r),loc=0;
        if(br-bl<=1){
            for(int i=l;i<=r;i++){
                t[a[i]]++;
            }
            for(int i=l;i<=r;i++){
                if(t[a[i]]>t[loc]||(t[a[i]]==t[loc]&&a[i]<loc)){
                    loc=a[i];
                }
            }
            for(int i=l;i<=r;i++){
                t[a[i]]=0;
            }
        }
        else{
            for(int i=l;i<=T*bl;i++){
                t[a[i]]++;
            }
            for(int i=T*(br-1)+1;i<=r;i++){
                t[a[i]]++;
            }
            loc=f[bl+1][br-1];
            for(int i=l;i<=T*bl;i++){
                int pre=t[loc]+s[br-1][loc]-s[bl][loc];
                int now=t[a[i]]+s[br-1][a[i]]-s[bl][a[i]];
                if(now>pre||(now==pre&&loc>a[i])){
                    loc=a[i];
                }
            }
            for(int i=T*(br-1)+1;i<=r;i++){
                int pre=t[loc]+s[br-1][loc]-s[bl][loc];
                int now=t[a[i]]+s[br-1][a[i]]-s[bl][a[i]];
                if(now>pre||(now==pre&&loc>a[i])){
                    loc=a[i];
                }
                    
            }
            for(int i=l;i<=T*bl;i++){
                t[a[i]]=0;
            }
            for(int i=T*(br-1)+1;i<=r;i++){
                t[a[i]]=0;
            }
        }
        x=b[loc];
        cout<<x<<endl;
    }
    return 0;
}
//P1558
#include <bits/stdc++.h>
using namespace std;
int n,t,m,pos[500050],res[5000050],L[500050],R[500050];
int vis[40],sum[500050],a[500050];
void update(int l,int r,int z){
    int p=pos[l],q=pos[r];
    if(sum[p]){
        for(int i=L[p];i<=R[p];i++){
            a[i]=sum[p];
        }
    }
    sum[p]=0;
    if(sum[q]){
        for(int i=L[q];i<=R[q];i++){
            a[i]=sum[q];
        }
    }
    sum[q]=0;
    if(p==q){
        for(int i=l;i<=r;i++){
            a[i]=z;
        }
    }
    else{
        for(int i=l;i<=R[p];i++){
            a[i]=z;
        }
        for(int i=L[q];i<=r;i++){
            a[i]=z;
        }
        for(int i=p+1;i<=q-1;i++){
            sum[i]=z;
        }
    }
}
int solve(int x){
    int res=0;
    for(int i=L[x];i<=R[x];i++){
        if(vis[a[i]]==0){
            res++;
        }
        vis[a[i]]++;
    }
    return res;
}
int query(int l,int r){
    int p=pos[l],q=pos[r],res=0;
    if(sum[p]){
        for(int i=L[p];i<=R[p];i++){
            a[i]=sum[p];
        }
    }
    sum[p]=0;
    if(sum[q]){
        for(int i=L[q];i<=R[q];i++){
            a[i]=sum[q];
        }
    }
    sum[q]=0;
    if(p==q){
        for(int i=l;i<=r;i++){
            if(vis[a[i]]==0){
                res++;
            }
            vis[a[i]]++;
        }
    }
    else{
        for(int i=l;i<=R[p];i++){
            if(vis[a[i]]==0){
                res++;
            }
            vis[a[i]]++;
        }
        for(int i=L[q];i<=r;i++){
            if(vis[a[i]]==0){
                res++;
            }
            vis[a[i]]++;
        }
        for(int i=p+1;i<=q-1;i++){
            if(!sum[i]){
                res+=solve(i);
            }
            else{
                if(vis[sum[i]]==0){
                    res++;
                }
                vis[sum[i]]++;
            }
        }
    }
    return res;
}
int main(){
    ios::sync_with_stdio(0);
    cin>>n>>t>>m;
    int T=sqrt(n);
    for(int i=1;i<=T;i++){
        L[i]=R[i-1]+1;
        R[i]=i*T;
    }
    if(R[T]!=n){
        T++;
        L[T]=R[T-1]+1;
        R[T]=n;
    }
    for(int i=1;i<=T;i++){
        for(int j=L[i];j<=R[i];j++){
            pos[j]=i;
        }
    }
    for(int i=1;i<=n;i++){
        a[i]=1;
        sum[pos[i]]=1;
    }
    for(int i=1;i<=m;i++){
        int x,y,z;
        char opt;
        cin>>opt>>x>>y;
        if(x>y){
            swap(x,y);
        }
        if(opt=='C'){
            cin>>z;
            update(x,y,z);
        }
        if(opt=='P'){
            memset(vis,0,sizeof vis);
            cout<<query(x,y)<<endl;
        }
    }
    return 0;
}
//P1558
#include <bits/stdc++.h>
using namespace std;
int n,t,m,pos[500050],res[5000050],L[500050],R[500050];
int vis[40],sum[500050],a[500050];
void update(int l,int r,int z){
    int p=pos[l],q=pos[r];
    if(sum[p]){
        for(int i=L[p];i<=R[p];i++){
            a[i]=sum[p];
        }
    }
    sum[p]=0;
    if(sum[q]){
        for(int i=L[q];i<=R[q];i++){
            a[i]=sum[q];
        }
    }
    sum[q]=0;
    if(p==q){
        for(int i=l;i<=r;i++){
            a[i]=z;
        }
    }
    else{
        for(int i=l;i<=R[p];i++){
            a[i]=z;
        }
        for(int i=L[q];i<=r;i++){
            a[i]=z;
        }
        for(int i=p+1;i<=q-1;i++){
            sum[i]=z;
        }
    }
}
int solve(int x){
    int res=0;
    for(int i=L[x];i<=R[x];i++){
        if(vis[a[i]]==0){
            res++;
        }
        vis[a[i]]++;
    }
    return res;
}
int query(int l,int r){
    int p=pos[l],q=pos[r],res=0;
    if(sum[p]){
        for(int i=L[p];i<=R[p];i++){
            a[i]=sum[p];
        }
    }
    sum[p]=0;
    if(sum[q]){
        for(int i=L[q];i<=R[q];i++){
            a[i]=sum[q];
        }
    }
    sum[q]=0;
    if(p==q){
        for(int i=l;i<=r;i++){
            if(vis[a[i]]==0){
                res++;
            }
            vis[a[i]]++;
        }
    }
    else{
        for(int i=l;i<=R[p];i++){
            if(vis[a[i]]==0){
                res++;
            }
            vis[a[i]]++;
        }
        for(int i=L[q];i<=r;i++){
            if(vis[a[i]]==0){
                res++;
            }
            vis[a[i]]++;
        }
        for(int i=p+1;i<=q-1;i++){
            if(!sum[i]){
                res+=solve(i);
            }
            else{
                if(vis[sum[i]]==0){
                    res++;
                }
                vis[sum[i]]++;
            }
        }
    }
    return res;
}
int main(){
    ios::sync_with_stdio(0);
    cin>>n>>t>>m;
    int T=sqrt(n);
    for(int i=1;i<=T;i++){
        L[i]=R[i-1]+1;
        R[i]=i*T;
    }
    if(R[T]!=n){
        T++;
        L[T]=R[T-1]+1;
        R[T]=n;
    }
    for(int i=1;i<=T;i++){
        for(int j=L[i];j<=R[i];j++){
            pos[j]=i;
        }
    }
    for(int i=1;i<=n;i++){
        a[i]=1;
        sum[pos[i]]=1;
    }
    for(int i=1;i<=m;i++){
        int x,y,z;
        char opt;
        cin>>opt>>x>>y;
        if(x>y){
            swap(x,y);
        }
        if(opt=='C'){
            cin>>z;
            update(x,y,z);
        }
        if(opt=='P'){
            memset(vis,0,sizeof vis);
            cout<<query(x,y)<<endl;
        }
    }
    return 0;
}
//P6177
#include <bits/stdc++.h>
#define int long long
using namespace std;
int n,m,tot,ver[100010],hed[100010],nxt[100010],dfn[100010],idx[100010],cnt;
int dep[100010],fa[100010],top[100010],siz[100010],son[100010],arr[100010];
int T,w[100010],x,a[100010],blg[100010],L[100010],R[100010];
bitset<40040> f[210][210],ans; // 210 > sqrt(40000) ≈ 200

void add(int a,int b){
    ver[++tot]=b,nxt[tot]=hed[a],hed[a]=tot;
}

void dfs1(int u,int faa){
    dep[u]=dep[faa]+1;
    fa[u]=faa;
    siz[u]=1;
    for(int i=hed[u];i;i=nxt[i]){
        int v=ver[i];
        if(v==faa){
            continue;
        }
        dfs1(v,u);
        if(siz[v]>siz[son[u]]){
            son[u]=v;
        }
    }
}

void dfs2(int u,int tp){
    top[u]=tp;
    idx[++cnt]=u;
    dfn[u]=cnt;
    a[cnt]=w[u];
    if(son[u]){
        dfs2(son[u],tp);
    }
    for(int i=hed[u];i;i=nxt[i]){
        int v=ver[i];
        if(v==fa[u]||v==son[u]){
            continue;
        }
        dfs2(v,v);
    }
}

inline void pre(){
    // 修改1:重新计算L,R,因为T已经改变
    for(int i=1;i<=n;i++){
        blg[i]=(i-1)/T+1;
    }
    int num=blg[n];
    for(int i=1;i<=num;i++){
        L[i]=(i-1)*T+1;
        R[i]=min(i*T,n);
    }
    // 修改2:重置f数组
    for(int i=1;i<=num;i++){
        f[i][i].reset();
        for(int j=L[i];j<=R[i];j++){
            f[i][i].set(a[j]);
        }
    }
    // 修改3:合并区间
    for(int i=1;i<=num;i++){
        for(int j=i+1;j<=num;j++){
            f[i][j]=f[i][j-1]|f[j][j];
        }
    }
}

inline void Ask(int l,int r){
    if(blg[l]==blg[r]){
        for(int i=l;i<=r;i++){
            ans.set(a[i]);
        }
        return;
    }
    // 修改4:检查中间块是否存在
    if(blg[l]+1<=blg[r]-1){
        ans|=f[blg[l]+1][blg[r]-1];
    }
    for(int i=l;i<=R[blg[l]];i++){
        ans.set(a[i]);
    }
    for(int i=L[blg[r]];i<=r;i++){
        ans.set(a[i]);
    }
}

inline void Qus(int u,int v){
    while(top[u]!=top[v]){
        if(dep[top[u]]<dep[top[v]]){
            swap(u,v);
        }
        Ask(dfn[top[u]],dfn[u]);
        u=fa[top[u]];
    }
    if(dep[u]>dep[v]){
        swap(u,v);
    }
    Ask(dfn[u],dfn[v]);
}

signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0); // 添加这行
    cout.tie(0); // 添加这行
    
    cin>>n>>m;
    T=max(1ll,(int)sqrt(n)); // 修改5:动态计算T
    
    for(int i=1;i<=n;i++){
        cin>>arr[i];
        w[i]=arr[i];
    }
    sort(arr+1,arr+1+n);
    arr[0]=unique(arr+1,arr+1+n)-arr-1;
    for(int i=1;i<=n;i++){
        w[i]=lower_bound(arr+1,arr+1+arr[0],w[i])-arr;
    }
    for(int i=1;i<n;i++){
        int a,b;
        cin>>a>>b;
        add(a,b);
        add(b,a);
    }
    dfs1(1,0);
    dfs2(1,1);
    pre(); // 调用预处理
    
    x=0; // 初始化x
    while(m--){
        int u,v;
        ans.reset();
        cin>>u>>v;
        u^=x;
        Qus(u,v);
        x=ans.count();
        cout<<x<<'\n'; // 修改6:用'\n'代替endl
    }
}

 

posted @ 2026-05-20 20:28  heccqwq  阅读(4)  评论(0)    收藏  举报