CF Edu Round 71

CF Edu Round 71

A There Are Two Types Of Burgers

Greedy casually simulate what

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
#define MAXN 200006
int n , m;
int A[MAXN];
int b , p , f , h , c;
int main() {
    int T;cin >> T;
    while( T-- ) {
        cin >> b >> p >> f >> h >> c;
        int res = 0;
        if( h > c ) {
            if( b > 2 * p ) b -= 2 * p , res += p * h;
            else { printf("%d\n",( b / 2 ) * h); continue; }
            if( b > 2 * f ) printf("%d\n",res + f * c);
            else printf("%d\n", res + ( b / 2 ) * c);
        } else {
            if( b > 2 * f ) b -= 2 * f , res += f * c;
            else { printf("%d\n",( b / 2 ) * c); continue; }
            if( b > 2 * p ) printf("%d\n",res + p * h);
            else printf("%d\n", res + ( b / 2 ) * h);
        }
    }
}

B Square Filling

Greedy, left enumeration down from the top left corner, if it can be painted coating, final judgment about enough.

#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<cstdio>
using namespace std;
#define MAXN 56
int A[MAXN][MAXN];
int n , m;
bool book[MAXN][MAXN];
vector<pair<int,int> > ans;
int main() {
    cin >> n >> m;
    for( int i = 1 ; i <= n ; ++ i )
        for( int j = 1 ; j <= m ; ++ j ) scanf("%d",&A[i][j]);
    for( int i = 1 ; i <= n ; ++ i ) {
        for( int j = 1 ; j <= m ; ++ j ) if( A[i][j] ) {
            if( ( i == n || j == m )  ) if(!book[i][j]){ return puts("-1") , 0; } else continue;
            if( A[i][j] == 1 && A[i + 1][j] == 1 && A[i + 1][j + 1] == 1 && A[i][j + 1] == 1 )
                book[i][j] = book[i+1][j] = book[i+1][j+1] = book[i][j + 1] = 1 , ans.push_back( make_pair( i , j ) );
            else if( !book[i][j] ) return puts("-1") , 0;
        }
    }
    cout << ans.size() << endl;
    for( int i = 0 ; i < ans.size() ; ++ i )
        printf("%d %d\n",ans[i].first , ans[i].second);
}

C Gas Pipeline

Just look like a linear dp

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define MAXN 300006
#define int long long
typedef long long ll;
using namespace std;
ll dp[MAXN][2] , len;
char s[MAXN];
signed main() {
    int T; cin >> T;
    while( T --> 0 ) {
        ll n, a, b;
        scanf("%lld%lld%lld%s", &n, &a, &b , s);
        len = strlen(s);
        dp[0][0] = b, dp[0][1] = 0x3f3f3f3f3f3f3f3f;
        for (int i = 1; i <= len; i++)
            if (s[i - 1] == '1')
                dp[i][1] = dp[i - 1][1] + a + 2 * b , dp[i][0] = 0x3f3f3f3f3f3f3f3f;
            else
                dp[i][1] = min( ( a << 1 ) + dp[i - 1][0], dp[i - 1][1] + a) + ( b << 1 ),
                dp[i][0] = min( a + dp[i - 1][0] , ( a << 1 ) + dp[i - 1][1] ) + b;
        printf("%lld\n",dp[len][0]);
    }
}

D Number Of Permutations

About inclusion and exclusion, the total number of permutations of - a first sequence - the order of the second order are both +

Calculation is very simple, do just fine with factorial

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <iostream>
using namespace std;
#define P 998244353
#define MAXN 300006
#define int long long
int n;
pair<int,int> A[MAXN];
int J[300050]; 
bool cmp1(pair<int,int> a,pair<int,int> b) {
    return a.first == b.first ? a.second < b.second : a.first < b.first;
} 
bool CMP(pair<int,int> a,pair<int,int> b) {
    return a.second < b.second;
}
signed main() {
    J[0] = 1; for (int i = 1; i <= 300000; ++i) J[i] = J[i - 1] * 1ll * i % P;
    scanf("%lld", &n);
    for (int i = 1; i <= n; ++i)
        scanf("%lld%lld", &A[i].first, &A[i].second);
    sort(A + 1, A + 1 + n, cmp1);
    int cur = 1 , ans = J[n];
    int l = 0;
    for (int i = 1; i <= n; ++i)
        if (A[i].first != A[i - 1].first) cur *= J[l], l = 1, cur %= P;
        else l++;
    cur *= J[l] , cur %= P , ans -= cur;
    bool flg = 1;
    for (int i = 1; i <= n; ++i)
        if (A[i].second < A[i - 1].second) { flg = 0; break; }
    if (flg) {
        cur = 1 , l = 0;
        for (int i = 1; i <= n; ++i) 
            if (A[i].first != A[i - 1].first || A[i].second != A[i - 1].second) 
                cur *= J[l], l = 1 , cur %= P;
            else l++;
        cur *= J[l], cur %= P , ans += cur;
    }
    sort(A + 1, A + 1 + n, CMP);
    cur = 1, l = 0;
    for (int i = 1; i <= n; ++i) {
        if (A[i].second != A[i - 1].second)
            cur *= J[l] , cur %= P , l = 1;
        else ++ l;
    }
    cur *= J[l] , cur %= P , ans -= cur;
    printf("%lld\n", (ans % P + P) % P);
    return 0;
}

E XOR Guessing

Ywh prostitute had a random examination room. . .

However, in practice very simple. .

Consider 7 7 into the front and rear, top 100 numbers before all the blank 7, 7 after the blank all 100 numbers, done

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstring>
using namespace std;
int pre , aft;
int main() {
    cout << '?' ;
    for( int i = 1 ; i <= 100 ; ++ i ) cout << ' ' << i;
    cout << endl;
    fflush( stdout );
    cin >> pre;
    cout << '?';
    for( int i = 1 ; i <= 100 ; ++ i ) cout << ' ' << ( i << 7 );
    cout << endl;
    fflush( stdout );
    cin >> aft;
    int res = 0;
    res |= ( pre & ( ( 1 << 8 ) - 1 ) << 7 );
    res |= ( aft & ( 1 << 7 ) - 1 );
    cout << '!' << ' ' <<  res << endl;
    fflush( stdout );
}

F Remainder Problem

Flood problem

The second operation, if $ y> \ sqrt n $ naive to direct violence

Otherwise, each time after a pre-processing operations at $ y \ leq \ sqrt n $ answers

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
typedef long long ll;
using namespace std;
#define MAXN 500006
#define MXBL 730
int t, x, y;
ll buc[MAXN] , S[MXBL][MXBL] , res ;
signed main() {
    int T;cin >> T;
    while( T --> 0 ) {
        scanf("%d%d%d", &t, &x, &y);
        if (t != 1) {
            if (x < MXBL ) printf("%lld\n", S[x][y]);
            else {
                res = 0; for (int j = y; j < MAXN; j += x) res += buc[j];
                printf("%lld\n", res);
            }
        } else {
            for (int j = 1; j < MXBL; ++j) S[j][x % j] += y;
            buc[x] += y;
        }
    }
}

G Indie Album

ACAM good question

In fact, he did not very good at acam. . . This is the way to learn to write questions after the game a bit acam

Of course, many people have written on the test of generalized suffix tree automata + chain split.

It is not just yijan Assembly (... wtcl

Found suffix automaton various board wrote much of the band are guys who see the title string seconds ah. .


First of all query string to build ac automatic machine, and then fail to establish the tree out.

Without considering the complexity of the query offline, and then run for each of the tree fail in a text string query, the nodes go to +1, and then ask for the number of each of the string which is the string that appears subtree and .

But complexity is obviously doing wrong, but the way to find this question very special text string, all text strings also form a tree structure, so consider this tree dfs text string constituted with a similar Technology incremental method after adding a character will be more of a position +1, -1, and this position will leave dfs, intermediate statistics about all the answers on this string on it.

+ Single point, requires a check interval fenwick tree, the complexity of the \ (O (TlogT) \)

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
#define MAXN 400006
int n , m;
char ch[MAXN];
 
int trie[MAXN][26] , fail[MAXN * 26] , ncnt = 0;
int T[MAXN];
int dfn;
void add( int x , int c ) {
    while( x <= dfn ) T[x] += c , x += x & -x;
}
int que( int x ) {
    int ret = 0;
    while( x > 0 ) ret += T[x] , x -= x & -x;
    return ret;
}
vector< pair<int,int> > ff[MAXN];
int ins( char* P ) {
    int cur = 0 , len = strlen( P );
    for( int i = 0 ; i < len ; ++ i ) {
        int v = P[i] - 'a';
        if( !trie[cur][v] ) trie[cur][v] = ++ncnt;
        cur = trie[cur][v];
    }
    return cur;
}
queue<int> Q;
vector<int> F[MAXN] , G[MAXN];
void build(  ) {
    int cur;
    for( int i = 0 ; i < 26 ; ++ i ) if( trie[0][i] )
        Q.push( trie[0][i] ) , fail[trie[0][i]] = 0;
    while( !Q.empty( ) ) {
        cur = Q.front() , Q.pop();
        F[fail[cur]].push_back( cur );
        for( int i = 0 ; i < 26 ; ++ i ) {
            if( trie[cur][i] )
                fail[trie[cur][i]] = trie[fail[cur]][i] ,
                Q.push( trie[cur][i] );
            else
                trie[cur][i] = trie[fail[cur]][i];
        }
    }
}
int L[MAXN] , R[MAXN];
void predfs( int u ) {
    L[u] = ++ dfn;
    for( int i = 0 ; i < F[u].size() ; ++ i ) predfs( F[u][i] );
    R[u] = dfn;
}
int ans[MAXN];
void work( int u , int p ) {
    p = trie[p][ch[u] - 'a'];
    add( L[p] , 1 );
    for( int i = 0 ; i < G[u].size() ; ++ i )
        work( G[u][i] , p );
    for( int i = 0 ; i < ff[u].size() ; ++ i )
        ans[ff[u][i].second] = que( R[ff[u][i].first] ) - que( L[ff[u][i].first] - 1 );
    add( L[p] , -1 );
}
char P[MAXN];
int ffa[MAXN];
int main() {
    cin >> n;
    for( int i = 1 , t , opt ; i <= n ; ++ i ) {
        scanf("%d ",&opt);
        if( opt == 1 ) { scanf("%c",&ch[i]) , ffa[i] = 0 , G[0].push_back( i ); continue; }
        scanf("%d %c",&t,&ch[i]);
        ffa[i] = t , G[t].push_back( i );
        getchar();
    }
    cin >> m;
    for( int i = 1 , t ; i <= m ; ++ i ) {
        scanf("%d%s",&t,P);
        int x = ins( P );
        ff[t].emplace_back( make_pair( x , i ) );
    }
    build( );
    predfs( 0 );
    for( int i = 1 ; i <= n ; ++ i ) if( !ffa[i] )
        work( i , 0 );
    for( int i = 1 ; i <= m ; ++ i ) printf("%d\n",ans[i]);
}

Guess you like

Origin www.cnblogs.com/yijan/p/cf1207.html