codeforces 855 div3 a-g

Powering the Hero (hard version)

考虑到题目并没有让我们输出每一次的卡牌 所以对于每次遇到的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 ;
int n ; 
int a[maxn] ; 
priority_queue<int> q ; 
signed main(){
    t = read() ; 
    while(t--){
        n = read() ; 
        for(int i = 1 ; i <= n ; i++)
            a[i] = read() ; 
        while(!q.empty()) q.pop() ;
        int ans = 0 ; 
        for(int i = 1 ; i <= n ; i++){
            if(a[i] != 0)
                q.push(a[i]) ; 
            else if(q.size()){
                ans += q.top() ; 
                q.pop() ; 
            }
        }
        printf("%lld\n" , ans) ; 
    }
    return 0 ;
 }

D:直接用字符串哈希即可 反正也是On的 每次考虑把断掉的两个拼在一起就行了 

#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 ;
}
#define ull unsigned long long 
int t ; 
int n ; 
char in[maxn] ;
int base = 13331 ; 
ull hsh[maxn] ; 
map<ull ,int  > mp ; 
ull p[maxn] ; 
ull gethsh(int l , int r){
    return (hsh[r] - hsh[l - 1] * p[r - l + 1]); 
}
void pre(){
    p[0] = 1 ; 
    for(int i = 1; i <= 200000 ; i++)
        p[i] = p[i - 1] * base ; 
}
signed main(){
    t = read() ; 
    pre() ; 
    while(t--){
        n = read() ; mp.clear() ; int ans = 0 ; 
        scanf("%s" , in + 1 ) ; 
        for(int i = 1 ; i <= n ; i++)
            hsh[i] = (hsh[i - 1] * base + in[i]) ; 
        for(int i = 2 ; i < n - 1 ; i++){
            int nhsh = (gethsh(1 , i - 1) * p[n - i - 1]  + gethsh(i + 2 , n) ) ; 
            if(!mp[nhsh])
                ans++ , mp[nhsh]= 1 ;// printf("i  :%lld \n" , i); 
        }
        int nhsh =  gethsh(3 , n); 
//        printf("%lld\n" , )
        if(!mp[nhsh])
            ans++ , mp[nhsh]= 1 ;// printf("yes \n"); 
        nhsh = gethsh(1 , n - 2) ; 
         if(!mp[nhsh])
                ans++ , mp[nhsh]= 1 ; 
        printf("%lld\n" , ans) ; 
    }
    return 0 ;
 }

 

Unforgivable Curse (hard version)

 E2 的话 直接分三类情况讨论即可 注意到k太小的时候是可以随便换位的 k太大的时候是不能换位的 k不大不小的时候是不能换位的 对于可以换位的地方 统计一下字母的数量是否一样 然后不能换位的位置看一下对应位置是否一样 
#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 ; 
char in1[maxn] , in2[maxn] ; 
int n   , k  ; 
int cnt1[30] , cnt2[30] ; 
signed main(){
    t = read() ; 
    while(t--){
        n = read() , k = read() ; 
        memset(cnt1 , 0 , sizeof(cnt1)) ; 
        memset(cnt2 , 0 , sizeof(cnt2)) ; 
        scanf("%s" , in1 + 1) ; 
        scanf("%s" , in2 + 1) ; 
        if(k * 2 <= n ){
            for(int i = 1 ;  i <= n ; i++)
                cnt1[in1[i] -'a'+ 1]++ ; 
            for(int i = 1 ; i <= n ; i++)
                cnt2[in2[i] -'a'+ 1]++ ; 
            bool flag = 0 ; 
            for(int i = 1 ; i <= 26 ; i++)
                if(cnt1[i] != cnt2[i]) flag = 1 ; 
            if(flag == 1){
                printf("no\n") ; 
            }
            else printf("yes\n") ; 
        }
        else if(k >= n){
            bool flag = 0 ; 
            for(int i = 1 ; i <= n ; i++)    
                if(in1[i] != in2[i] )
                    flag = 1 ; 
            if(flag == 1){
                printf("no\n") ; 
            }
            else printf("yes\n") ; 
        }
        else if(k * 2 > n){
            for(int i = 1 ; i <= n - k ; i++)
                cnt1[in1[i] -'a'+ 1]++ ,cnt2[in2[i] -'a'+ 1]++ ;
            for(int i = k + 1 ; i <= n ; i++)
                cnt1[in1[i] -'a'+ 1]++ ,cnt2[in2[i] -'a'+ 1]++ ;
            bool flag = 0 ; 
            for(int i = 1 ; i <= 26 ; i++)
                if(cnt1[i] != cnt2[i]) flag = 1 ; 
            for(int i = n - k + 1 ; i <= k ; i++)
                if(in1[i] != in2[i])
                    flag = 1 ; 
            if(flag == 1){
                printf("no\n") ; 
            }
            else printf("yes\n") ; 
        }
    }
    return 0 ;
 }

 

Dasha and Nightmares 考虑每次去掉某一位数 然后把是奇数的设置成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 n ; 
unordered_map<int,int> mp[30] ; 
int target[30] ; 
int cnt[30] , ans = 0; 
char in[5000010] ; 
signed main(){
//    freopen("test.in" , "r" , stdin) ; 
//    freopen("test.out" , "w" , stdout);
    n = read() ; 
//    printf("temp : %lld \n" , 1 << 26) ; 
    for(int i = 1 ; i <= 26 ; i++){
        target[i] = ((1 << 26) - 1) ^ (1 << (i - 1)) ; 
//        printf("target : %lld \n" , target[i]) ; 
    }
    for(int ii = 1 ; ii <= n ; ii++){
        scanf("%s" , in + 1) ; int len = strlen(in + 1) ; 
        for(int i = 1 ; i <= 26 ; i++ ) cnt[i] = 0 ; 
        for(int i = 1 ; i <= len ; i++)
            cnt[in[i] - 'a' + 1]++ ; 
        int now = 0 ; 
        for(int i = 1; i <= 26 ; i++ )
            if(cnt[i] % 2 == 1)
                now ^= (1 << (i - 1)) ; 
        for(int i = 1 ; i <= 26 ; i++){
            if(cnt[i] == 0 && mp[i][target[i] ^ now]){
                ans += mp[i][target[i] ^ now] ; 
            }
        }
        for(int i = 1 ; i <= 26 ; i++)
            if(cnt[i] == 0)
                mp[i][now] += 1 ; 
    }
    printf("%lld\n" , ans) ;
    return 0 ;
 }

Symmetree

#include<bits/stdc++.h>
using namespace std ;
#define maxn 400100
#define int long long
#include <chrono>
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 ; 
 int n ; 
unsigned int hsh[maxn] ; 
vector<int> G[maxn] ; 
const unsigned int mask =  (chrono::steady_clock::now().time_since_epoch().count());
unsigned int shift(unsigned int x){
    x ^= mask ; 
    x ^= x << 13;
    x ^= x >> 7;
    x ^= x << 17;
    x ^= mask;
    return x; 
}
void dfs(int x , int fa){
    hsh[x] = 1 ; //printf("x : %lld \n" , x) ; 
    for(int i = 0 ; i < G[x].size() ; i++){
        int v = G[x][i] ; 
        if(v == fa) continue ; 
        dfs(v , x ) ; 
        hsh[x] += shift(hsh[v]) ; 
    }
}
bool check(int x , int fa ){
    int sum = 0 ; 
    for(int i = 0 ; i < G[x].size() ; i++){
        int v = G[x][i] ;
        if(v == fa) continue ;  
        sum ^= hsh[v] ; 
    }
    if(sum == 0){
        return 1 ; 
    }
    int node = sum ; 
        for(int i = 0 ; i < G[x].size() ; i++){
            int v = G[x][i] ; 
            if(v == fa) continue ;  
            if(hsh[v] == node){
                return check(v , x) ; 
             }
        }
    return 0 ; 
}
signed main(){
//    freopen("test.in" , "r" , stdin) ; 
//    freopen("test.out" , "w" , stdout);
    t = read() ; 
    while(t--){
        n = read() ;  s.clear() ; mp.clear() ; 
        for(int i = 1 ; i <= n ; i++)
            G[i].clear() , hsh[i] = 0 ; 
        for(int i = 1 ; i < n ; i++){
            int u = read() , v  =read() ; 
            G[u].push_back(v) ; 
            G[v].push_back(u) ; 
        }
        dfs(1 , 1) ; 
        if(check(1 , 1)) printf("Yes\n") ; 
        else printf("No\n") ; 
    }
    return 0 ;
 }

树哈希模板 建议是去oiwiki上面学习一下https://oi-wiki.org/graph/tree-hash/

posted @ 2023-03-03 22:07  Vellichor_zht  阅读(80)  评论(0)    收藏  举报