【HT-072-Div.2】核桃CSP-S组模拟赛 & XRCOI Round 4

核桃OJ

难度明显不到 S?我倒开花了 2h 就做完了。

A

注意到 \(2^x-2^y\) 在二进制下就是从小到大第 \([y,x)\) 位为 1,其余位为 0 的数。

转成二进制处理,差分即可。

#include<bits/stdc++.h>
#define rep(i,l,r) for(int i=(l),qwp=(r);i<=qwp;i++)
#define per(i,r,l) for(int i=(r),qwp=(l);i>=qwp;i--)
#define repll(i,l,r) for(ll i=(l),qwp=(r);i<=qwp;i++)
#define perll(i,r,l) for(ll i=(r),qwp=(l);i>=qwp;i--)
#define pb push_back
#define ins insert
#define clr clear
#define uset unordered_set
#define umap unordered_map
using namespace std;
namespace ax_by_c{
typedef long long ll;
const int N=1e6+5;
char _c[16],s[N];
int _x[300],n,a[N],b[N],m;
void slv(int _csid,int _csi){
    rep(i,0,9)_c[i]='0'+i;
    rep(i,10,15)_c[i]='A'+i-10;
    rep(i,0,15)_x[(int)_c[i]]=i;
    scanf("%s",s+1);
    for(int i=1;s[i];i++)n=i;
    reverse(s+1,s+1+n);
    rep(i,1,n){
        a[i*4-4]=bool(_x[(int)s[i]]&1);
        a[i*4-3]=bool(_x[(int)s[i]]&2);
        a[i*4-2]=bool(_x[(int)s[i]]&4);
        a[i*4-1]=bool(_x[(int)s[i]]&8);
    }
    scanf("%d",&m);
    rep(i,1,m){
        int x,y;
        scanf("%d %d",&x,&y);
        b[x]^=1,b[y]^=1;
    }
    rep(i,1,n*4-1)b[i]^=b[i-1];
    rep(i,1,n){
        int p=0;
        p+=(a[i*4-4]^b[i*4-4])*1;
        p+=(a[i*4-3]^b[i*4-3])*2;
        p+=(a[i*4-2]^b[i*4-2])*4;
        p+=(a[i*4-1]^b[i*4-1])*8;
        s[i]=_c[p];
    }
    per(i,n,1)putchar(s[i]);
}
void main(){
	// ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int T=1,csid=0;
	// scanf("%d",&csid);
	// scanf("%d",&T);
	rep(i,1,T)slv(csid,i);
}
}
int main(){
	string __name="xor";
	if(__name!=""){
		freopen((__name+".in").c_str(),"r",stdin);
		freopen((__name+".out").c_str(),"w",stdout);
	}
	ax_by_c::main();
	return 0;
}
/*
g++ -std=c++14 -O2 -Wall -Wextra "-Wl,--stack=200000000" A.cpp -o A.exe
A.exe
*/

B

这种操作在 https://www.luogu.com.cn/problem/AT_agc004_f 中亦有记载。

根据那题的套路,我们将序列的奇数位全部 flip,此时原操作就变为了 swap。

于是使用线段树维护区间 flip 和区间 1 的个数即可。

#include<bits/stdc++.h>
#define rep(i,l,r) for(int i=(l),qwp=(r);i<=qwp;i++)
#define per(i,r,l) for(int i=(r),qwp=(l);i>=qwp;i--)
#define repll(i,l,r) for(ll i=(l),qwp=(r);i<=qwp;i++)
#define perll(i,r,l) for(ll i=(r),qwp=(l);i>=qwp;i--)
#define pb push_back
#define ins insert
#define clr clear
#define uset unordered_set
#define umap unordered_map
using namespace std;
namespace ax_by_c{
typedef long long ll;
const int N=1e6+5;
int fr(){
    int n=0;
    char c=getchar();
    while(c<'0'||'9'<c)c=getchar();
    while('0'<=c&&c<='9')n=n*10+c-48,c=getchar();
    return n;
}
struct DS1{
    struct node{
        int s,z;
    }tr[N*4];
    void pu(int u){
        tr[u].s=tr[u<<1].s+tr[u<<1|1].s;
    }
    void pd_(int u,int l,int z){
        if(!z)return ;
        tr[u].s=l-tr[u].s;
        tr[u].z^=1;
    }
    void pd(int u,int l,int r){
        int mid=l+((r-l)>>1);
        pd_(u<<1,mid-l+1,tr[u].z);
        pd_(u<<1|1,r-mid,tr[u].z);
        tr[u].z=0;
    }
    void bld(int u,int l,int r,char *a){
        if(l==r){
            tr[u].s=a[l]=='1';
            return ;
        }
        int mid=l+((r-l)>>1);
        bld(u<<1,l,mid,a);
        bld(u<<1|1,mid+1,r,a);
        pu(u);
    }
    void upd(int u,int l,int r,int ql,int qr){
        if(ql<=l&&r<=qr){
            pd_(u,r-l+1,1);
            return ;
        }
        pd(u,l,r);
        int mid=l+((r-l)>>1);
        if(ql<=mid)upd(u<<1,l,mid,ql,qr);
        if(mid+1<=qr)upd(u<<1|1,mid+1,r,ql,qr);
        pu(u);
    }
    int Q(int u,int l,int r,int ql,int qr){
        if(ql<=l&&r<=qr)return tr[u].s;
        pd(u,l,r);
        int mid=l+((r-l)>>1),res=0;
        if(ql<=mid)res+=Q(u<<1,l,mid,ql,qr);
        if(mid+1<=qr)res+=Q(u<<1|1,mid+1,r,ql,qr);
        return res;
    }
}tr1,tr2;
int n,q;
char a[N],b[N];
void slv(int _csid,int _csi){
    n=fr(),q=fr();
    scanf("%s",a+1);
    scanf("%s",b+1);
    rep(i,1,n){
        if(i&1)a[i]^=1,b[i]^=1;
    }
    tr1.bld(1,1,n,a),tr2.bld(1,1,n,b);
    rep(_,1,q){
        int op=fr();
        if(op==1){
            int l=fr(),r=fr();
            tr1.upd(1,1,n,l,r);
        }
        if(op==2){
            int l=fr(),r=fr();
            tr2.upd(1,1,n,l,r);
        }
        if(op==3){
            int x=fr(),y=fr(),z=fr();
            if((x-y)%2){
                if(tr1.Q(1,1,n,x,x+z-1)+tr2.Q(1,1,n,y,y+z-1)==z)putchar('1');
                else putchar('0');
            }
            else{
                if(tr1.Q(1,1,n,x,x+z-1)==tr2.Q(1,1,n,y,y+z-1))putchar('1');
                else putchar('0');
            }
        }
    }
}
void main(){
	// ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int T=1,csid=0;
	// scanf("%d",&csid);
	// scanf("%d",&T);
	rep(i,1,T)slv(csid,i);
}
}
int main(){
	string __name="transform";
	if(__name!=""){
		freopen((__name+".in").c_str(),"r",stdin);
		freopen((__name+".out").c_str(),"w",stdout);
	}
	ax_by_c::main();
	return 0;
}
/*
g++ -std=c++14 -O2 -Wall -Wextra "-Wl,--stack=200000000" A.cpp -o A.exe
A.exe
*/

C

根据条件 3,直接枚举二分图的两个部。

容易发现最优策略一定是连出若干个互不接触的交叉。

考虑 dp,设 \(f_{x,y}\) 为上部前 \(x\) 个和下部前 \(y\) 个连出最多的交叉数。

维护上部和下部中最后一次出现某个值的位置,容易转移。

时间复杂度 \(O(n^3)\)

#include<bits/stdc++.h>
#define rep(i,l,r) for(int i=(l),qwp=(r);i<=qwp;i++)
#define per(i,r,l) for(int i=(r),qwp=(l);i>=qwp;i--)
#define repll(i,l,r) for(ll i=(l),qwp=(r);i<=qwp;i++)
#define perll(i,r,l) for(ll i=(r),qwp=(l);i>=qwp;i--)
#define pb push_back
#define ins insert
#define clr clear
#define uset unordered_set
#define umap unordered_map
using namespace std;
namespace ax_by_c{
typedef long long ll;
const int N=305;
int n,a[N],b[N];
int hsh[N*2],hc;
int f[N][N],lsta[N][N*2],lstb[N][N*2];
int cal(){
    rep(i,1,n){
        rep(j,1,hc)lsta[i][j]=lsta[i-1][j];lsta[i][a[i]]=i;
        rep(j,1,hc)lstb[i][j]=lstb[i-1][j];lstb[i][b[i]]=i;
    }
    rep(i,1,n)rep(j,1,n){
        f[i][j]=max(f[i-1][j],f[i][j-1]);
        if(lstb[j-1][a[i]]&&lsta[i-1][b[j]])f[i][j]=max(f[i][j],f[lsta[i-1][b[j]]-1][lstb[j-1][a[i]]-1]+1);
    }
    return f[n][n];
}
void slv(int _csid,int _csi){
    scanf("%d",&n);
    rep(i,1,n)scanf("%d",&a[i]),hsh[++hc]=a[i];
    rep(i,1,n)scanf("%d",&b[n-i+1]),hsh[++hc]=b[n-i+1];
    sort(hsh+1,hsh+1+hc),hc=unique(hsh+1,hsh+1+hc)-hsh-1;
    rep(i,1,n)a[i]=lower_bound(hsh+1,hsh+1+hc,a[i])-hsh;
    rep(i,1,n)b[i]=lower_bound(hsh+1,hsh+1+hc,b[i])-hsh;
    int ans=cal();
    rep(_,1,n-1){
        rep(i,0,n-1)a[i]=a[i+1];a[n]=b[n];
        per(i,n,2)b[i]=b[i-1];b[1]=a[0];
        ans=max(ans,cal());
    }
    printf("%d\n",ans);
}
void main(){
	// ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int T=1,csid=0;
	// scanf("%d",&csid);
	// scanf("%d",&T);
	rep(i,1,T)slv(csid,i);
}
}
int main(){
	string __name="light";
	if(__name!=""){
		freopen((__name+".in").c_str(),"r",stdin);
		freopen((__name+".out").c_str(),"w",stdout);
	}
	ax_by_c::main();
	return 0;
}
/*
g++ -std=c++14 -O2 -Wall -Wextra "-Wl,--stack=200000000" A.cpp -o A.exe
A.exe
*/

D

考虑点分治,统计跨过某点路径的答案,只需设计算法快速求出若干个数两两相加的答案。

对每一位计算答案,排序后可以分讨转化为求区间内数的个数,此时总复杂度为 \(O(n\log^2 n\log V)\)

考虑基数排序,同时发现求的区间是关于数的一次函数,双指针即可,此时总复杂度为 \(O(n\log n\log V)\)

#include<bits/stdc++.h>
#define rep(i,l,r) for(int i=(l),qwp=(r);i<=qwp;i++)
#define per(i,r,l) for(int i=(r),qwp=(l);i>=qwp;i--)
#define repll(i,l,r) for(ll i=(l),qwp=(r);i<=qwp;i++)
#define perll(i,r,l) for(ll i=(r),qwp=(l);i>=qwp;i--)
#define UQ(hsh,hc) (sort((hsh)+1,(hsh)+1+(hc)),(hc)=unique((hsh)+1,(hsh)+1+(hc))-(hsh)-1)
#define pb push_back
#define ins insert
#define clr clear
#define uset unordered_set
#define umap unordered_map
using namespace std;
namespace ax_by_c{
typedef long long ll;
const int N=1e5+5;
namespace CALC{
    int n,a[N],cnt[10],a_[N];
    ll res;
    ll cal(vector<int> &_A_){
        res=0;
        n=_A_.size();
        rep(i,1,n)a[i]=_A_[i-1];
        int cur=1;
        rep(p,0,6){
            rep(i,0,9)cnt[i]=0;
            rep(i,1,n)cnt[a[i]/cur%10]++;
            rep(i,1,9)cnt[i]+=cnt[i-1];
            per(i,n,1){
                int t=a[i]/cur%10;
                a_[cnt[t]]=a[i],cnt[t]--;
            }
            rep(i,1,n)a[i]=a_[i];
            int j1=0,j2=0,j3=0,j4=0;
            rep(i,1,n){
                int x=a[i]%(cur*10);
                while(j1<n&&a[j1+1]%(cur*10)<=cur*7-1-x)j1++;
                while(j1&&a[j1]%(cur*10)>cur*7-1-x)j1--;
                while(j2<n&&a[j2+1]%(cur*10)<=cur*6-1-x)j2++;
                while(j2&&a[j2]%(cur*10)>cur*6-1-x)j2--;
                while(j3<n&&a[j3+1]%(cur*10)<=cur*17-1-x)j3++;
                while(j3&&a[j3]%(cur*10)>cur*17-1-x)j3--;
                while(j4<n&&a[j4+1]%(cur*10)<=cur*16-1-x)j4++;
                while(j4&&a[j4]%(cur*10)>cur*16-1-x)j4--;
                if(x<=cur*6)res+=j1-j2;
                if(cur*6<x&&x<cur*7)res+=j1-j4+n;
                if(cur*7<=x)res+=j3-j4;
            }
            cur*=10;
        }
        return res;
    }
}
int n;
struct E{
    int v,w;
};
vector<E>g[N];
bool rem[N];
int asz,sz[N],rt,val;
void _dfs(int u,int fa){
    sz[u]=1;
    int w=0;
    for(auto e:g[u]){
        if(e.v==fa||rem[e.v])continue;
        _dfs(e.v,u);
        sz[u]+=sz[e.v];
        w=max(w,sz[e.v]);
    }
    w=max(w,asz-sz[u]);
    if(w<val)rt=u,val=w;
}
vector<int>nums[N];
void dfs(int u,int fa,int dis,int to){
    nums[to].pb(dis);
    for(auto e:g[u]){
        if(e.v==fa||rem[e.v])continue;
        dfs(e.v,u,dis+e.w,to);
    }
}
ll ans;
void dfz(int pp,int asz_){
    val=asz=asz_,_dfs(pp,0);
    pp=rt,_dfs(pp,0);
    rem[pp]=1;
    nums[pp].clr();
    for(auto e:g[pp])if(!rem[e.v]){
        nums[e.v].clr();
        dfs(e.v,pp,e.w,e.v);
        ans-=CALC::cal(nums[e.v]);
        for(auto it:nums[e.v])nums[pp].pb(it);
    }
    nums[pp].pb(0);
    ans+=CALC::cal(nums[pp]);
    for(auto e:g[pp])if(!rem[e.v])dfz(e.v,sz[e.v]);
}
void slv(int _csid,int _csi){
    scanf("%d",&n);
    rep(i,1,n-1){
        int u,v,w;
        scanf("%d %d %d",&u,&v,&w);
        g[u].pb({v,w});
        g[v].pb({u,w});
    }
    dfz(1,n);
    ans/=2;
    printf("%lld\n",ans);
}
void main(){
	// ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int T=1,csid=0;
	// scanf("%d",&csid);
	// scanf("%d",&T);
	rep(i,1,T)slv(csid,i);
}
}
int main(){
	string __name="666";
	if(__name!=""){
		freopen((__name+".in").c_str(),"r",stdin);
		freopen((__name+".out").c_str(),"w",stdout);
	}
	ax_by_c::main();
	return 0;
}
/*
g++ -std=c++14 -O2 -Wall -Wextra "-Wl,--stack=200000000" A.cpp -o A.exe
A.exe
*/
posted @ 2025-08-10 18:06  ax_by_c  阅读(78)  评论(0)    收藏  举报