Manthan, Codefest 19 problem solution

Manthan, Codefest 19

A XORinacci

Obviously cycling section 3

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
#define MAXN 200006
int n , m , t;
int A[MAXN];
int main() {
    int T;cin >> T;
    while( T-- ) {
        cin >> n >> m >> t;
        if( t % 3 == 0 ) cout << n << endl;
        else if( t % 3 == 1 ) cout << m << endl;
        else cout << (n ^ m) << endl;
    }

}

B Uniqueness

And the FST. . . . .

Clearly evident in pursuit of a single log write speed of a successful double log fst

It can actually be half + check, the beginning of discrete just fine.

In fact, \ (n ^ 2log \) well I think, just too lazy to change the 2333

#pragma GCC optimize(3)
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<set>
using namespace std;
#define MAXN 200006
int n , m , t;
int A[MAXN];
int a[MAXN] , M[MAXN];
bool chk( int len ) {
    for( int i = 1 ; i <= n - len + 1 ; ++ i ) {
        int flg = 0;
        memset( M , 0 , sizeof M );
        for( int j = 1 ; j <= n ; ++ j ) {
            if( j >= i && j <= i + len - 1 ) continue;
            if( M[a[j]] ) {flg = 1;break;}
            M[a[j]] = 1;
        }
        if( !flg ) return true;
    }
    return false;
}
int main() {
    cin >> n;
    for( int i = 1 ; i <= n ; ++ i ) scanf("%d",&A[i]) , a[i] = A[i];
    sort( A + 1 , A + 1 + n );
    int sz = unique( A + 1 , A + 1 + n ) - A - 1;
    for( int i = 1 ; i <= n ; ++ i ) a[i] = lower_bound( A + 1 , A + 1 + sz , a[i] ) - A;
    int l = 0 , r = n;
    while( l <= r ) {
        int mid = l + r >> 1;
        if( chk( mid ) ) r = mid - 1;
        else l = mid + 1;
    }
    cout << l << endl;
}

C Magic Grid

First constructed $ 4 \ times 4 $ matrix

This matrix is ​​then directly +16, +32 ... copy $ \ frac {n} {4} \ times \ frac {n} {4} $ times like

Because each small matrix is ​​0, so certainly a large matrix is ​​0

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
#define int long long
#define MAXN 1006
int n , data[MAXN][MAXN] , M[6][6];
signed main() {
    cin >> n;
        int x = 15, tot = 0;
    int now = 0;
    for (int i = 1; i <= 4; ++i)
        for (int j = 1; j <= 4; ++j)
            M[i][j] = x - now, now++;
    n /= 4;
    int cur = 0;
    for( int i = 0 ; i < n ; ++ i )
        for( int j = 0 ; j < n ; ++ j ) {
            for( int k = 1 ; k <= 4 ; ++ k )
                for( int kk = 1 ; kk <= 4 ; ++ kk )
                    data[i*4+k][j*4+kk] = M[k][kk] + cur * 16;
            ++ cur;
        }
    for( int i = 1 ; i <= n * 4 ; ++ i ) {
        for (int j = 1; j <= n * 4; ++j)
            printf("%lld ", data[i][j]);
        puts("");
    }
}

D Restore Permutation

Fenwick tree + half

Obviously the last position can decide how much the last one, then it becomes a problem almost identical, from the enumeration and half forward just fine.

However, the practice is to find the solution to a problem position 1, and then back to the position +1, with a tree line, although some excellent but a single log. . Not write ah 2333

After all, cf 2e5 apparently just run the

#include<cstring>
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<map>
using namespace std;
#define MAXN 200006
#define int long long
int n;

int T[MAXN];
void add( int x , int c ) {
    while( x <= n ) T[x] += c , x += x & -x;
}
int que( int x ) {
    int ret = 0;
    while( x > 0 ) ret += T[x] , x -= x & -x;
    return ret;
}
int S[MAXN];
int ans[MAXN];
signed main() {
    cin >> n;
    for( int i = 1 ; i <= n ; ++ i ) scanf("%lld",&S[i]);
    for( int i = 1 ; i <= n ; ++ i ) add( i , i );
    for( int i = n ; i >= 1 ; -- i ) {
        int l = 0 , r = n;
        while( l <= r ) {
            int mid = l + r >> 1;
            if( que( mid ) > S[i] ) r = mid - 1;
            else l = mid + 1;
        }
        add( l , -l );
        ans[i] = l;

    }
    for( int i = 1 ; i <= n ; ++ i ) printf("%lld ",ans[i]);
}

E Let Them Slide

First enumerate position 1ton

Then we maintain an array for each Land Rrepresent the current position in the array can slide interval

Clearly mobile number for each location and are only \ (\ SUM A \) , can accept, simply take a look at the data structure to maintain maximum range just fine

#include <cstdio>
#include <cstring>
#include <set>
#include <algorithm>
#include <iostream>
using namespace std;
int n, w;
#define MAXN 1000006
typedef long long ll;
int read(  ) {
    char ch = ' '; int res = 0;
    while( ch < '0' || ch > '9' ) ch = getchar();
    while( ch <= '9' && ch >= '0' ) { res *= 10 , res += ch - '0' , ch = getchar(); }
    return res;
}

ll T[MAXN << 2];
void mdfy(int rt,int l,int r,int L,int R,int valx) {
    if(L <= l && r <= R) { T[rt] += valx; return ; }
    int m = (l + r) >> 1;
    if(m >= L) mdfy( rt << 1 , l , m , L , R , valx );
    if(m <= R - 1) mdfy( rt << 1 | 1 , m + 1 , r , L , R , valx);
}
void work(int rt,int l,int r) {
    if (l == r) { printf("%lld ", T[rt]); return; }
    T[rt << 1] += T[rt] , T[rt << 1 | 1] += T[rt];
    int mid = (l + r) >> 1;
    work(rt << 1, l, mid) , work(rt << 1 | 1, mid + 1, r);
}

struct node {
    ll val;
    int pos;
    node(  ) { val = pos = 0; }
}A[1000500];

bool cmp( node a , node b ) {
    return a.val > b.val;
}

set<int> st;
int main() {
    n = read() , w = read();
    for (int i = 1 , l; i <= n; ++i) {
        st.clear();
        l = read();
        for (int j = 1; j <= l; ++j) A[j].pos = j, scanf("%lld", &A[j].val);
        int que = l , len = w - l + 1;
        sort(A + 1, A + 1 + l , cmp);
        for (int j = 1; j <= l; ++j) {
            int l = A[j].pos, r = A[j].pos + len - 1;
            auto it = st.lower_bound(A[j].pos), it1 = it;
            if (A[j].val < 0) r = min(r, que) , l = max(l, w - que + 1);
            if (it != st.end()) r = min(r, (*(it)) - 1);
            if (it1 != st.begin()) l = max(l, (*(--it1)) + len);
            if (l <= r) mdfy(1, 1, w, l, r, A[j].val);
            st.insert(A[j].pos);
        }
    }
    work(1, 1, w);
}

F Bits And Pieces

This topic is very interesting

We consider maintaining a data structure (in fact, violence), supports insert, query a number of digital as a subset of the current set number Can be internal through get operations

Because only if the query can be obtained, we know that, if a number $ a $ is a subset within two sets of figures, it is clear that you can get by with a number such that $ a $ is a subset of it.

So consider a number with dfs method to enumerate the subset. If a subset of this number have been twice, do not continue to enumerate a subset of this number, because it's all subsets certainly has been enumerated twice before.

So the overall complexity is $ 2 v $ of!

So put this question, inserted from the back, then consider it to or for each number, the current first decided to come up with a set of numbers set to 0, or when you can take a look at the whether from high to low 1, if not look for the current value of the variable 1 can get by with two numbers, if you can put the current value of this bit becomes 1.

Specific implementation can look at the code, a very nb of thinking. .

(However, I do not know what the question is narrated sosdp)

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define MAXN 2097156

int read(  ) {
    int res = 0; char ch = ' ';
    while( ch > '9' || ch < '0' ) ch = getchar();
    while( ch >= '0' && ch <= '9' ) res *= 10 , res += ch - '0' , ch = getchar();
    return res;
}

int cnt[MAXN];
void insert( int x , int y ) {
    if( cnt[x | y] >= 2 ) return;
    if( x == 0 ) { ++ cnt[y]; return; }
    insert( x & x - 1 , y | ( x & -x ) ) ,
    insert( x & x - 1 , y );
}
int n , ans = 0;
int A[MAXN];
int main() {
    cin >> n;
    for( int i = 1 ; i <= n ; ++ i ) A[i] = read();
    for( int i = n , cur ; i >= 1 ; -- i ) {
        if( i <= n - 2 ) {
            cur = 0;
            for( int j = 21 ; j >= 0 ; -- j ) if( ( ~ A[i] >> j & 1 ) && cnt[ cur | ( 1 << j ) ] == 2 )
                    cur |= ( 1 << j );
            ans = max( ans , A[i] | cur );
        }
        insert( A[i] , 0 );
    }
    cout << ans << endl;
}

G Polygons

First, we get the same pattern can have a vertex (emotional understanding)

Consider the k-edge took shape, it will certainly take a shape of about k number of sides, after all, does not increase the number of points Well ~

We want to take consideration of the current x-gon, before us clearly about the number of x-gon take over (or else why not take the number of polygons about it?), Increase the amount of the number of points at this time is obviously \ (\ Phi (the X-) \) , because each point can be seen as a $ 1 / x, 2 / x , 3 / x ... $, which is not relatively prime number at about the time it has won a .

Obviously, shape and two side edges shaped does not exist,

  • While clear-shaped, like a direct answer +1
  • When we choose two sides form an even-sided polygon, it means that we have chosen two sides shape. That is, unless only choose an equilateral triangle, are two sides will form on the election. Only select only one case of an equilateral triangle, only special sentenced to $ k = 1 $.

In summary, when $ k = 1 $ 3 can be directly output, other times sort $ \ Phi $, from small to large and then to take a $ k + 2 $ like.

Due to an obvious conclusion, $ \ phi (d) \ leq \ phi (x) $ where $ d $ is a divisor of $ x $, we will in the choice of pre-$ x $-gon finished selecting all of the $ x $ submultiple polygon.

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
#define MAXN 1000006
#define int long long
int n , k;

int p[MAXN] , cnt , phi[MAXN];
void init( ) {
    phi[1] = 1;
    for( int i = 2 ; i < MAXN ; ++ i ) {
        if( !p[i] ) p[++cnt] = i , phi[i] = i - 1;
        for( int j = 1 ; j <= cnt && p[j] * i < MAXN ; ++ j ) {
            p[p[j] * i] = 1;
            if( i % p[j] == 0 ) { phi[ p[j] * i ] = phi[i] * ( p[j] ); break; }
            phi[p[j] * i] = phi[i] * ( p[j] - 1 );
        }
    }
}

signed main() {
    init();
    cin >> n >> k;
    if( k == 1 ) return puts( "3" ) , 0;
    sort( phi + 1 , phi + 1 + n );
    int res = 0;
    for( int i = 1 ; i <= k + 2 ; ++ i ) res += phi[i];
    cout << res << endl;
}

H Red Blue Tree

  • It is a pigeon

Guess you like

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