Codeforces #174 Div2

Cows and Primitive Roots

  原根,目前只有暴力求解,看了百度百科才知道。因为 x < p,  且 p <= 2000

View Code
#include<stdio.h>

#include<stdlib.h>





int p;



int pow( int x, int n ){

    int res = 1;

    while( n ){

        if( n&1 ) res = (res*x)%p;

        x = x*x%p;

        n >>= 1; 

    }

    return res;

}



bool legal( int x ){

    if( pow( x, p-1 ) - 1 ) return false;

    else{

        for(int i = 1; i < p-1; i++ )

            if( (pow(x,i)-1) == 0 ) return false;

        return true;

    }

}

int main(){

    while( scanf("%d", &p) != EOF)

    {

        int res = 0;

        for(int x = 1; x < p; x++ )

        {

            if( legal( x ) )

                res++;

        }

        printf("%d\n", res );    

    }

    return 0;

}

 

Cows and Poker Game

  题目描述的,最后一句话感觉有点坑,若其他人为 F或 A, 自己是A或I 才可以举手,只需要统计I数量,

然后分析即可。

View Code
#include<stdio.h>

#include<string.h>





const int N = 200007;

char str[N];



int main(){

    int n;

    while( scanf("%d", &n) != EOF )

    {

        scanf("%s", str );

        int len = strlen(str);

        int cnt_A = 0, cnt_I = 0;    

        for(int i = 0; i < len; i++)

            if( str[i] == 'I' ) cnt_I++;

            else if( str[i] == 'A' ) cnt_A++;    

        if( cnt_I == 1 ) printf("1\n");

        else if( cnt_I == 0 ) printf("%d\n", cnt_A);

        else    printf("0\n");

    }

    return 0;

}

 

Cows and Sequence

  区间更新,单点更新,区间求和,可以用线段树来维护,时间复杂度为 Nlog(N) ,

不过要注意原本里头有1个元素了,极限再添加 N个, 则最大有 N+1 个节点

  解法2,主要还是区间更新然后删除最后一个节点时候的处理,其实可以借鉴线段树区间更新,

中的 push_down 操作,借助辅助数组来实现,代码可以很精简。

解法一代码

View Code
#include<stdio.h>

#include<string.h>

#include<stdlib.h>

#include<algorithm>

using namespace std;



#define lson l,m,rt<<1

#define rson m+1,r,rt<<1|1

typedef long long LL;



const int N = 200010;



LL sum[N<<2], add[N<<2];

void push_up( int rt ){

    sum[rt] = sum[rt<<1] + sum[rt<<1|1];

}

void push_down( int rt, int m){

    if( add[rt] ){

        add[rt<<1] += add[rt];

        add[rt<<1|1] += add[rt];    

        sum[rt<<1] += (LL)(m-(m>>1))*add[rt];

        sum[rt<<1|1] += (LL)(m>>1)*add[rt];

        add[rt] = 0;

    }

}



void build( int l, int r, int rt ){

    add[rt] = sum[rt] = 0;

    if( l == r ) return;

    int m = (l+r)>>1;

    build( lson );

    build( rson );

    //push_up( rt );

}

void update( int L, int R, LL c, int l, int r,int rt ){

    if( (L<=l) && (r<=R) ){

        add[rt] += c;

        sum[rt] += (LL)c*(r-l+1);

        return;    

    }

    push_down( rt, r-l+1 );

    int m = (l+r)>>1;

    if( L <= m ) update( L, R, c, lson );

    if( m < R ) update( L, R, c, rson );

    push_up( rt );

}

LL query( int L, int R, int l, int r, int rt ){

    if( (L<=l) && (r<=R) )

        return sum[rt];

    push_down( rt, r-l+1 );

    int m = (l+r)>>1;

    LL ret = 0;

    if( L <= m ) ret += query( L, R, lson );

    if( m < R )  ret += query( L, R, rson );

    return ret;

}



int main(){

//    freopen("1.in", "r", stdin);

//    freopen("test.out","w",stdout);



    int T, n = 1, maxn = 200001;

    build( 1, maxn, 1 );    



    scanf("%d", &T);

    for(int i = 0; i < T; i++){

        int op, a, b;

        scanf("%d", &op);

        if( op == 1 ){

            scanf("%d%d", &a, &b );

            update( 1,a, b,  1,maxn,1 ); 

        }

        else if( op == 2 ){

            scanf("%d", &a );

            n++;

            update( n,n,a, 1,maxn, 1 );        

        }

        else{

            if( n > 1 ) {

                LL tmp = query( n,n, 1,maxn,1 );    

                update( n,n, -tmp, 1,maxn, 1 );

                --n;    

            }    

        }

    

        LL res = query( 1, maxn, 1, maxn, 1 );

//        printf("%lld\n", res );

                printf("%.9lf\n", res*1./n );

    }    

    return 0;

}

解法二代码

View Code
#include<stdio.h>

#include<string.h>

#include<stdlib.h>



typedef long long LL;



const int N = 2e5+10;

LL s, a[N], c[N];



int main(){

    int n = 1, m;

    scanf("%d", &m);

    while( m-- ){

        int op, x, y;

        scanf("%d", &op);

        if( op == 1 ){

            scanf("%d%d", &x,&y);    

            s += (1LL)*x*y; c[x] += y;

        }

        else if( op == 2 ){

            scanf("%d", &y);

            s += y; a[++n] = y;

        }

        else{

            s -= a[n]; a[n] = 0;

            c[n-1] += c[n]; 

            s -= c[n]; c[n] = 0;

            --n;

        }    

        printf("%.9lf\n", s*1./n);    

    }

    return 0;

}

 

Cow Program

  因为 A【1】 每次都在变换,但是操作对于x而言只有 +a[x] ,与 -a[x],

若其第二次回到 1 位置,若为 +a[x], 则陷入死循环,若为 -a[x],则必定 1-a[1] 终断,

所以我们可以得出结论,a[1] = i ,的值虽然变换,但不对后面的产生影响,所以可以使用

记忆化搜索或者DP来解。

View Code
#include<stdio.h>

#include<stdlib.h>

#include<string.h>

#include<algorithm>

using namespace std;



typedef long long LL;



const int N = 2e5+10;



LL dp[2][N];

int n, a[N];

int vis[2][N];



LL dfs( int i, int cur, int x ){

    if( x <= 0 || x > n ) return 0;

    // 循环,继续走下去回陷入循环 

    if( (vis[cur][x] == i) || (vis[cur][x] == -1 ) ) return -1;



    if( vis[cur][x] ) return dp[cur][x];

    vis[cur][x] = i;    

    

    LL tmp = dfs( i, !cur, x + (cur?(-a[x]):a[x]) );



    if( tmp == -1 ) return (vis[cur][x] = -1);

    else    return dp[cur][x]= tmp+a[x];



}

int main(){

    scanf("%d", &n );

    for(int i = 2; i <= n; i++)

        scanf("%d", &a[i] );

    for(int i = 1; i <= n-1; i++)

    {

        vis[0][1]=0,a[1] = i;

        LL y = dfs(i, 0, 1);

        printf("%lld\n", y );    

    }

    return 0;

}

 

Coin Troubles

  还没有写,A了后再来补充~~~

你可能感兴趣的:(codeforces)