2023年1月训练计划

摘要

1月14/15号就是ICPC香港站了,考完期末考试回学校复习,准备知乎上刷刷专题,做几套abc和arc

abc283e dp

#include<bits/stdc++.h>
using namespace std;
const int N=1010;
int f[N][2][2][2];// i-1 i i+1
int n,m,a[N][N];
int check(int i,int x,int y,int z){
    
    
    for(int j=1;j<=m;j++){
    
    
        int X=a[i][j]^x;
        int Y=a[i-1][j]^y;
        int Z=a[i+1][j]^z;
        if(i-1==0)Y=100;
        if(i+1==n+1)Z=100;
        if(X==Y||X==Z)continue;
        if(j==1&&a[i][j]!=a[i][j+1])return 0;
        if(j==m&&a[i][j]!=a[i][j-1])return 0;
        if(j>1&&j<m&&a[i][j]!=a[i][j-1]&&a[i][j]!=a[i][j+1])return 0;
    }
    return 1;
}
signed main(){
    
    
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    cin>>n>>m;
    for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)cin>>a[i][j];
    for(int j=1;j<=m;j++)a[0][j]=a[n+1][j]=2;
    memset(f,0x3f,sizeof f);
    
    for(int i=1;i<=n;i++){
    
    
        for(int x=0;x<=1;x++){
    
    
            for(int y=0;y<=1;y++){
    
    
                for(int z=0;z<=1;z++){
    
    
                    if(check(i,x,y,z)){
    
    
                        if(i> 1)f[i][x][y][z]=min(f[i-1][y][0][x],f[i-1][y][1][x])+z;
                        if(i==1)f[i][x][y][z]=x+y+z;
                    }
                }
            }
        }
    }
    int ans=0x3f3f3f3f;
    for(int x=0;x<=1;x++)for(int y=0;y<=1;y++)ans=min(ans,f[n][x][y][0]);
    if(ans==0x3f3f3f3f)ans=-1;
    cout<<ans;
}

abc283f 线段树

#include<bits/stdc++.h>
#define ls u<<1
#define rs u<<1|1
using namespace std;
const int N=2e5+10;
int n,v[N],a[N*4],b[N*4],c[N*4],d[N*4];

void pushup(int u){
    
    
    a[u]=min(a[ls],a[rs]);
    b[u]=min(b[ls],b[rs]);
    c[u]=min(c[ls],c[rs]);
    d[u]=min(d[ls],d[rs]);
}
void ins(int t,int u,int x,int val,int l=1,int r=n){
    
    
    if(l==r){
    
    
        if(t==1)a[u]=val;
        if(t==2)b[u]=val;
        if(t==3)c[u]=val;
        if(t==4)d[u]=val;
        return;
    }
    int mid=l+r>>1;
    if(x<=mid)ins(t,ls,x,val,l,mid);
    else ins(t,rs,x,val,mid+1,r);
    pushup(u);
}
int query(int t,int u,int ql,int qr,int l=1,int r=n){
    
    
    if(l>qr||r<ql)return 1e9;
    if(ql<=l&&r<=qr){
    
    
        if(t==1)return a[u];
        if(t==2)return b[u];
        if(t==3)return c[u];
        if(t==4)return d[u];
    }
    int mid=l+r>>1;
    return min(query(t,ls,ql,qr,l,mid),query(t,rs,ql,qr,mid+1,r));
}
int ans[N];

signed main(){
    
    
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    cin>>n;
    memset(a,0x3f,sizeof a);
    memset(b,0x3f,sizeof b);
    memset(c,0x3f,sizeof c);
    memset(d,0x3f,sizeof d);
    for(int i=1;i<=n;i++)cin>>v[i];
    memset(ans,0x3f,sizeof ans);
    for(int i=1;i<=n;i++){
    
    
        int &x=ans[i];
        x=min(x,i+v[i]+query(1,1,1,v[i]-1));ins(1,1,v[i],-i-v[i]);
        x=min(x,i-v[i]+query(2,1,v[i]+1,n));ins(2,1,v[i],-i+v[i]);
    }
    for(int i=n;i>=1;i--){
    
    
        int &x=ans[i];
        x=min(x,-i+v[i]+query(3,1,1,v[i]-1));ins(3,1,v[i],i-v[i]);
        x=min(x,-i-v[i]+query(4,1,v[i]+1,n));ins(4,1,v[i],i+v[i]);
    }
    for(int i=1;i<=n;i++)cout<<ans[i]<<" ";
}

abc283g 线性基

#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef long long ll;
int d[61],tot;
int n,L,R;
//构造序列的线性基
void insert(ll x)
{
    
    
    for(int i=60;i>=0;i--)
    {
    
    
        if(x&(1ll<<i))//注意,如果i大于31,前面的1的后面一定要加ll
        {
    
    
            if(d[i])x^=d[i];
            else
            {
    
    
                d[i]=x;
                tot++;
                break;//插入成功就退出
            }
        }
    }
}

//求最大值
ll ans()
{
    
    
    ll anss=0;
    for(int i=60;i>=0;i--)//记得从线性基的最高位开始
    if((anss^d[i])>anss)anss^=d[i];
    return anss;
 }   
//求最小值
ll query_min()
{
    
    
    for (int i=0;i<=60;i++)
        if (d[i])
            return d[i];
    return 0;
}
//求第k小值
void work()//处理线性基
{
    
    
	for(int i=1;i<=60;i++)
	for(int j=1;j<=i;j++)
	if(d[i]&(1ll<<(j-1)))d[i]^=d[j-1];
}


ll k_th(ll k)
{
    
    
	if(k==1)return 0;
	//特判一下,假如k=1,并且原来的序列可以异或出0,就要返回0,tot表示线性基中的元素个数,n表示序列长度
	
	k--;//类似上面,去掉0的情况,因为线性基中只能异或出不为0的解
// 	work();
    if(k>(1ll<<tot))return -1;//最多只有2的tot次方种异或情况
	ll ans=0;
	for(int i=0;i<=60;i++)
	if(d[i]!=0)
	{
    
    
		if(k%2==1)ans^=d[i];
		k/=2;
	}
	return ans;
}

signed main(){
    
    
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    cin>>n>>L>>R;
    for(int i=1,x;i<=n;i++)cin>>x,insert(x);
    work();
    for(int i=L;i<=R;i++)cout<<k_th(i)<<" ";
}




线段树

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
#define ls u<<1
#define rs u<<1|1
int s[N*4],lz[N*4],a[N*4],b[N*4],c[N*4];
int n,q,l,r;
void pushup(int u){
    
    
    a[u]=min(a[ls],a[rs]);
    s[u]=s[ls]+s[rs];
}
void pushdown(int u){
    
    
    if(lz[u]){
    
    
        a[ls]+=lz[u];
        lz[ls]+=lz[u];
        a[rs]+=lz[u];
        lz[rs]+=lz[u];
        lz[u]=0;
    }
}
void build(int u,int l=1,int r=n){
    
    
    lz[u]=s[u]=0;
    if(l==r){
    
    
        a[u]=b[l];
        return;
    }
    int mid=l+r>>1;
    build(ls,l,mid);build(rs,mid+1,r);
    pushup(u);
}
void update(int u,int ql,int qr,int l=1,int r=n){
    
    
    if(ql>r||qr<l)return;
    if(ql<=l&&r<=qr){
    
    
        if(a[u]>1){
    
    a[u]--,lz[u]--;return;}
        else if(l==r){
    
    s[u]++,a[u]=b[l];return;}
    }
    pushdown(u);
    int mid=l+r>>1;
    update(ls,ql,qr,l,mid);
    update(rs,ql,qr,mid+1,r);
    pushup(u);
}

int query(int u,int ql,int qr,int l=1,int r=n){
    
    
    if(ql>r||qr<l)return 0;
    if(ql<=l&&r<=qr)return s[u];
    int mid=l+r>>1;
    pushdown(u);
    return query(ls,ql,qr,l,mid)+query(rs,ql,qr,mid+1,r);
}

signed main(){
    
    
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    while(cin>>n>>q){
    
    
        for(int i=1;i<=n;i++)cin>>b[i];
        build(1);
        while(q--){
    
    
            string op;
            cin>>op>>l>>r;
            if(op[0]=='a')update(1,l,r);
            else cout<<query(1,l,r)<<'\n';
        }
    }
}

abc285h类欧几里得

#include<bits/stdc++.h>
#define ll unsigned long long
#define ull ll
using namespace std;
 
// sum{i=0}^{n-1} floor((a*i+b)/c)
ull f(ull a,ull b,ull c,ull n){
    
    
    ull ret=0;
    ret+=b/c*n;b%=c;
    ret+=a/c*n*(n-1)/2;a%=c;
    if(a*n+b<c)return ret;
    return ret+f(c,(a*n+b)%c,a,(a*n+b)/c);
}
signed main(){
    
    
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    int T;
    cin>>T;
    while(T--){
    
    
        int n,m,r;
        cin>>n>>m>>r;
        ll ans=0;
        n=(n-r)/m+1;
        for(int k=0;k<30;k++){
    
    
            ans+=f(m,r+(1ll<<k),1ll<<k+1,n)-f(m,r,1ll<<k+1,n);
        }
        cout<<ans<<'\n';
    }
}

abc282e

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=550;
int n,m,p[N],a[N];
struct node{
    
    
    int a,b,w;
    bool operator<(const node&t)const{
    
    
        return w>t.w;
    }
};
int find(int x){
    
    
    if(p[x]==x)return x;
    return p[x]=find(p[x]);
}
int qpow(int a,int b){
    
    
    int ans=1;
    while(b){
    
    
        if(b&1)ans=ans*a%m;
        b/=2;
        a=a*a%m;
    }
    return ans;
}
int cal(int i,int j){
    
    
    return (qpow(a[i],a[j])+qpow(a[j],a[i]) )%m;
}
signed main(){
    
    
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    vector<node>v;
    cin>>n>>m;
    for(int i=1;i<=n;i++)cin>>a[i];
    for(int i=1;i<=n;i++){
    
    
        for(int j=1;j<i;j++){
    
    
            v.push_back({
    
    i,j,cal(i,j)});
        }
    }
    for(int i=1;i<=n;i++)p[i]=i;
    sort(v.begin(),v.end());
    int ans=0;
    for(auto [a,b,c]:v){
    
    
        if(find(a)==find(b))continue;
        p[find(a)]=find(b);
        ans+=c;
    }
    cout<<ans;
}

abc282f

#include<bits/stdc++.h>
using namespace std;
int n,m,q;
const int N=1e5+10;
int f[N][21];
int L[N],R[N];
signed main(){
    
    
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    cin>>n;
    for(int i=1;i<=n;i++){
    
    
        for(int j=0;i+(1<<j)-1<=n;j++){
    
    
            f[i][j]=++m;
            L[m]=i;
            R[m]=i+(1<<j)-1;
        }
    }
    cout<<m<<'\n';
    for(int i=1;i<=m;i++)cout<<L[i]<<" "<<R[i]<<'\n';
    cout.flush();
    cin>>q;
    while(q--){
    
    
        int l,r;
        cin>>l>>r;
        int k=__lg(r-l+1);
        int L1=l,R1=l+(1<<k)-1;
        int R2=r,L2=r-(1<<k)+1;
        cout<<f[L1][k]<<" "<<f[L2][k]<<'\n';
        cout.flush();
    }
}



















猜你喜欢

转载自blog.csdn.net/supreme567/article/details/128527337
今日推荐