Codeforces Round 882 (Div. 2) A-D

发布时间 2023-07-07 22:05:42作者: Vellichor_zht

AThe Man who became a God 

假设sum为 omiga abs(a[i] - a[i -1]) 1 <= i <= n 

只有设置断点的时候,假设设置在t和t-1之间 the value才会减少abs(a[t]-a[t-1]) 

所以把差距最大的几个地方分段就行了

#include<bits/stdc++.h>
using namespace std ;
#define maxn 400100
#define int long long
int read(){
    int ans = 0 , f = 1 ; char ch = getchar() ;
    while ( !isdigit(ch) ){ if( ch == '-' ) f = -1 ; ch = getchar() ; }
    while ( isdigit(ch) ) ans = (ans * 10) + (ch ^ '0') , ch = getchar() ;
    return ans * f ;
}
int t = read() ; 
int a[maxn] , cha[maxn]; 
signed main(){
    while(t--){
        int n = read() , k = read() - 1 , sum = 0 ; 
        for(int i = 1 ; i <= n ; i++){
            a[i] = read() ; 
            sum += cha[i] = abs(a[i] - a[i - 1] ); 
        }
        cha[1] = 0 ; sum -= a[1] ; 
        sort(cha + 1 , cha + 1 + n) ; 
        for(int i = n ; i >= n - k + 1 ; i--)
            sum -= cha[i] ; 
        printf("%lld\n" , sum) ; 
    }
    return 0 ;
 }

BHamon Odyssey 

贪心 在能and到0并且后面也能and成0的地方就断

#include<bits/stdc++.h>
using namespace std ;
#define maxn 400100
#define int long long
int read(){
    int ans = 0 , f = 1 ; char ch = getchar() ;
    while ( !isdigit(ch) ){ if( ch == '-' ) f = -1 ; ch = getchar() ; }
    while ( isdigit(ch) ) ans = (ans * 10) + (ch ^ '0') , ch = getchar() ;
    return ans * f ;
}
int t = read() ;
int a[maxn] , qian[maxn] , hou[maxn] ; 
signed main(){
    while(t--){
        int n = read() ; 
         qian[1] = a[1] = read() ; 
         hou[1] = 0 ; 
        for(int i = 2 ; i <= n ;i++)
            a[i] = read() , qian[i] = qian[i - 1] & a[i] , hou[i] = 0 ; 
        hou[n] = a[n] ; 
        hou[n + 1] = 0 ;
        for(int i = n - 1; i >= 1 ; i--){
            hou[i] = hou[i + 1] & a[i] ; 
        }
        if(qian[n] != 0){
            printf("1\n") ; 
            continue ; 
        }
        int cnt = 0 ; 
        bool flag = 0 ; 
        int sum = 0 ; 
        for(int i = 1 ; i <= n ; i++){
            if(!flag){
                flag = 1 ;
                sum = a[i] ; 
            }
            else {
                sum &= a[i] ; 
            }
            if(sum == 0){
                if(hou[i + 1] == 0){
                    cnt++ ; 
                    flag = 0 ; 
                }
            }
        }
            
        printf("%lld\n" , cnt) ; 
    }
    return 0 ;
 }

CVampiric Powers, anyone?

 模拟之后可以发现其实本质上是找异或之后的最大子段 
注意到a最大只有255 所以异或之后也不超过255 利用类似前缀和性质即可 
#include<bits/stdc++.h>
using namespace std ;
#define maxn 400100
#define int long long
int read(){
    int ans = 0 , f = 1 ; char ch = getchar() ;
    while ( !isdigit(ch) ){ if( ch == '-' ) f = -1 ; ch = getchar() ; }
    while ( isdigit(ch) ) ans = (ans * 10) + (ch ^ '0') , ch = getchar() ;
    return ans * f ;
}
int t  = read() ; 
int cnt[500] ; 
signed main(){
    while(t--){
        int n = read() ; 
        for(int  i = 0 ; i < 256 ; i++) cnt[i] = 0 ; 
        int sum = 0 , ans = 0 ; 
        cnt[0] = 1 ; 
        for(int i = 1 ; i <= n ; i++){
            sum ^= read() ; 
            cnt[sum]= 1 ; 
            for(int i = 0 ; i < 256 ; i++)
                if(cnt[i]) ans = max(ans , sum ^ i) ; 
        }
        printf("%lld\n" , ans) ; 
    }
    return 0 ;
 }

Professor Higashikata

 以第二个样例为例模拟一遍 

 

#include<bits/stdc++.h>
using namespace std ;
#define maxn 300100
#define int long long
int read(){
    int ans = 0 , f = 1 ; char ch = getchar() ;
    while ( !isdigit(ch) ){ if( ch == '-' ) f = -1 ; ch = getchar() ; }
    while ( isdigit(ch) ) ans = (ans * 10) + (ch ^ '0') , ch = getchar() ;
    return ans * f ;
}
#define fi first 
#define se second 
int n , m , q ; 
pair<int,int> ques[maxn] , pi[maxn]; 
int val[maxn << 2] , a[maxn] , s[maxn] , sum , tag[maxn << 2]; 
char in[maxn] ; 
void pushdown(int o){
    tag[o << 1]= tag[o << 1 | 1]= tag[o] ; 
    val[o << 1 | 1] = val[o << 1] = tag[o] ; 
    tag[o] = 0 ; 
    return ; 
}
#define lr o << 1 
#define rr ((o << 1) | 1)
#define mid ((l + r) >> 1)
void modify(int o , int l , int r , int ql , int qr , int k){
    if(l > qr || r < ql) return ; 
    if(tag[o]) pushdown(o) ; 
    if(l >= ql && r <= qr){
        tag[o] = val[o] = k ; 
        return ; 
    }
    modify(lr , l , mid , ql , qr , k) ;
    modify(rr , mid + 1 , r , ql , qr , k ) ; 
    return ; 
}
int que(int o , int l , int r , int poss){
    if(tag[o]) pushdown(o) ; 
    if(l == r) return val[o] ; 
    if(poss <= mid) return que(lr , l , mid , poss) ; 
    else return que(rr , mid + 1 , r  , poss) ; 
}
int c[maxn] ; 
#define lowbit(x) (x & (-x))
void add(int pos , int x ){
    while(pos <= n){
//        printf("pos : %lld x : %lld \n" , pos , x) ; 
        c[pos] += x ; 
        pos += lowbit(pos) ; 
    }
    return ; 
}
int query(int pos){
    int suum = 0 ; 
    while(pos){
        suum += c[pos] ; 
        pos -= lowbit(pos) ; 
    }
    return suum ; 
}
vector<int> G[maxn] ; 
signed main(){
    n = read() ; m = read() , q = read() ; 
    scanf("%s" , in + 1) ;  
    for(int i = 1 ; i <= n ; i++)
        sum += s[i] = in[i] - '0' ; 
    for(int i = 1 ; i <= m ; i++)
        ques[i] = {read() , read()} ; 
    for(int i = m ; i >= 1 ; i--){
        modify(1 , 1 , n , ques[i].fi , ques[i].se , i) ; 
    }
    for(int i = 1 ; i <= n ; i++){
        a[i] = que(1 , 1 , n , i) ; 
//        printf("a[%lld] : %lld \n" , i , a[i]) ; 
        G[a[i]].push_back(i) ; 
    }
    int num = 0 ; 
    for(int i = 1 ; i <= m ; i++){
        if(G[i].size()){
            for(int j = 0 ; j < G[i].size() ; j++){
                int v = G[i][j] ; 
                a[v] = ++num ; 
//                printf("a[%lld] : %lld \n" , v , a[v]) ; 
                add(num , s[v]) ; 
            }
        }
    }
//    printf("num : %lld \n" , num) ; 
    while(q--){
        int x = read() ; 
        if(s[x] == 1){
            s[x] = 0 ; 
            sum-- ; 
            if(a[x] != 0){
                add(a[x] , -1) ; 
            }
        }
        else {
            s[x] = 1  ;
            sum++ ; 
            if(a[x] != 0)
                add(a[x] , 1) ;// printf("yes"); 
        }//
        printf("%lld\n" , min(sum , num ) - query(min(sum , num)) ) ; 
    }
    return 0 ;
 }