Codeforces Round #174 (Div. 2)

http://codeforces.com/contest/284

A:快速幂取模,套上模板枚举就行。当时脑子乱了,竟然想超数据类型了不行啊,快速幂取模就可以解决的。

B:大水题,很多人估计AB两题搞倒了。

C:线段树维护区间添加,单点询问,O(Nlog(n))做。当时做的时候直接把模板弄了过来结果中间有个错误,一直调啊调,到了最后才发现,超级郁闷。

View Code
By E_star, contest: Codeforces Round #174 (Div. 2), problem: (C) Cows and Sequence, Accepted, #

 #include <iostream>

#include <cstdio>

#include <cmath>

#include <vector>

#include <cstring>

#include <algorithm>

#include <string>

#include <set>

#include <functional>

#include <numeric>

#include <sstream>

#include <stack>

#include <map>

#include <queue>



#define CL(arr, val)    memset(arr, val, sizeof(arr))



#define ll long long

#define inf 0x7f7f7f7f

#define lc l,m,rt<<1

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

#define pi acos(-1.0)



#define L(x)    (x) << 1

#define R(x)    (x) << 1 | 1

#define MID(l, r)   (l + r) >> 1

#define Min(x, y)   (x) < (y) ? (x) : (y)

#define Max(x, y)   (x) < (y) ? (y) : (x)

#define E(x)        (1 << (x))

#define iabs(x)     (x) < 0 ? -(x) : (x)

#define OUT(x)  printf("%I64d\n", x)

#define lowbit(x)   (x)&(-x)

#define Read()  freopen("din.txt", "r", stdin)

#define Write() freopen("dout.txt", "w", stdout);





#define N 200007

#define M 26



using namespace std;



int a[N];

int n,len;



int val[4*N],lz[4*N];



void pushup(int rt)

{

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

}

void pushdown(int rt,int m)

{

    if (lz[rt])

    {

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

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

        val[rt<<1] += (m - (m>>1))*lz[rt];//�����[1,m/2]��m-m/2��

        val[rt<<1|1] += (m>>1)*lz[rt];//�ұ�[m/2+1,m]��m/2��

        lz[rt] = 0;

    }

}

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

{

    lz[rt] = 0;

    if (l == r)

    {

        val[rt] = 0;

        return ;

    }

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

    build(l,m,rt<<1);

    build(m + 1,r,rt<<1|1);

    pushup(rt);

}

void update(int L,int R,int sc,int l,int r,int rt)

{

//    printf("%d %d %d %d\n",L,R,l,r);

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

    {

        lz[rt] += sc;//����ҲҪ�ۼӵġ�

        val[rt] += sc*(ll)(r - l + 1);

        return ;

    }

    pushdown(rt,r - l + 1);

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

    if (L <= m) update(L,R,sc,l,m,rt<<1);

    if (R > m) update(L,R,sc,m + 1,r,rt<<1|1);

    pushup(rt);



}

int query(int x,int l,int r,int rt,int mk)

{

    if (l == r)

    {

        if (mk == 0)

        {

            val[rt] = 0;

        }

        return val[rt];

    }

    pushdown(rt,r - l + 1);

    int res = 0;

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

    if (x <= m) res = query(x,l,m,rt<<1,mk);

    else res = query(x,m + 1,r,rt<<1|1,mk);

    pushup(rt);

    return res;

}



int main()

{

//    Read();

    int i;

    int op,x,y;

    while (~scanf("%d",&n))

    {

        build(0,n,1);

        a[0] = 0;

        len = 0;

        double sum = 0;



        for (i = 0; i < n; ++i)

        {

            scanf("%d",&op);

            if (op == 3)

            {

                if (len >= 1)

                {

                    sum -= (a[len] + query(len,0,n,1,1));

                    query(len,0,n,1,0);

                    len--;

                }

            }

            if (op == 1)

            {

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

                update(0,x - 1,y,0,n,1);

                sum += (y*x);

            }

            if (op == 2)

            {



                scanf("%d",&y);

                a[++len] = y;

                sum += y;



            }

            printf("%lf\n",sum/(len + 1));

//

//            for (int j = 0; j <= 10; ++j)

//            {

//

//                printf("%d ",query(j,0,n,1,1));

//            }

//            printf("\n**********\n");

        }

    }

    return 0;

}

 

 

D: 

题意:给你一个序列 i(a1),a2,a3,a4......an  i分别取1,2,3,..n-1进行如下操作,x,y初始值为1,0. x + a[x],y + a[x] ;  x - a[x],y + a[x] ......一直这样循环下去,如果出现x <=0 || x > n 输出y的值,如果出现了循环环,就输出-1;

思路:

DP .dp[i][0]表示在i这个状态时执行加,1表示减,然后记忆化搜索一下看能否搜到x <=0 || x > n   如果搜到则返回y和,就是,路径上a[x]累加。否则返回-1;

View Code
By E_star, contest: Codeforces Round #174 (Div. 2), problem: (D) Cow Program, Accepted, #

 #include <iostream>

#include <cstdio>

#include <cmath>

#include <vector>

#include <cstring>

#include <algorithm>

#include <string>

#include <set>

#include <functional>

#include <numeric>

#include <sstream>

#include <stack>

#include <map>

#include <queue>



#define CL(arr, val)    memset(arr, val, sizeof(arr))



#define lc l,m,rt<<1

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

#define pi acos(-1.0)

#define ll __int64

#define L(x)    (x) << 1

#define R(x)    (x) << 1 | 1

#define MID(l, r)   (l + r) >> 1

#define Min(x, y)   (x) < (y) ? (x) : (y)

#define Max(x, y)   (x) < (y) ? (y) : (x)

#define E(x)        (1 << (x))

#define iabs(x)     (x) < 0 ? -(x) : (x)

#define OUT(x)  printf("%I64d\n", x)

#define lowbit(x)   (x)&(-x)

#define Read()  freopen("din.txt", "r", stdin)

#define Write() freopen("dout.txt", "w", stdout);







#define N 200007

using namespace std;



ll dp[N][2],a[N];

int n;



ll dp_dfs(int x,int mk)

{

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

    if (!dp[x][mk])

    {

        if (mk == 1)

        {

            dp[x][mk] = -1;

            ll res = dp_dfs(x - a[x],0);

            if (res != -1)

            dp[x][mk] = res + a[x];



        }

        else

        {

            dp[x][mk] = -1;

            ll res = dp_dfs(x + a[x],1);

            if (res != -1)

            dp[x][mk] = res + a[x];



        }

    }

    return dp[x][mk];

}

int main()

{

    int i;

    while (~scanf("%d",&n))

    {

        CL(a,0);  CL(dp,0);

        for (i = 2; i <= n; ++i) scanf("%I64d",&a[i]);

        dp[1][0] = -1; dp[1][1] = -1;

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

        {

            ll ans = dp_dfs(i + 1,1);

            if (ans != -1) ans += i;

            printf("%I64d\n",ans);

        }

    }

    return 0;

}

 

E:

题意:
给出n中不同面值的硬币,然后给出q种硬币数量之间的关系,求满足q中数量关系,且总价值为t的可能输%mod

思路:

乍一看是完全背包,可是怎样保证这样的数量关系呢。不好搞,后来看看别人的代码,超级给力,我们只要记录每个比他数量大的,然后添加一个自己就相当于所有比他大的都要添加一个,所以我们要把比他大的的值都加到他身上,然后添加时。就按照完全背包做就好了,这样就保证了添加进去的肯定满足数量关系。

View Code
#include <iostream>

#include <cstdio>

#include <cmath>

#include <vector>

#include <cstring>

#include <algorithm>

#include <string>

#include <set>

#include <functional>

#include <numeric>

#include <sstream>

#include <stack>

#include <map>

#include <queue>



#define CL(arr, val)    memset(arr, val, sizeof(arr))



#define ll __int64

#define inf 0x7f7f7f7f

#define lc l,m,rt<<1

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

#define pi acos(-1.0)



#define L(x)    (x) << 1

#define R(x)    (x) << 1 | 1

#define MID(l, r)   (l + r) >> 1

#define Min(x, y)   (x) < (y) ? (x) : (y)

#define Max(x, y)   (x) < (y) ? (y) : (x)

#define E(x)        (1 << (x))

#define iabs(x)     (x) < 0 ? -(x) : (x)

#define OUT(x)  printf("%I64d\n", x)

#define lowbit(x)   (x)&(-x)

#define Read()  freopen("din.txt", "r", stdin)

#define Write() freopen("dout.txt", "w", stdout);





#define N 307

#define M 100007



const int mod = 1000000007;

using namespace std;



int pre[N],next[N];



ll f[M],a[N];



int main()

{

    int n,i,j;

    int q,t;

    int x,y;

    scanf("%d%d%d",&n,&q,&t);



    for (i = 0; i < n; ++i) scanf("%I64d",&a[i]);



    CL(next,-1); CL(pre,-1);



    for (i = 0; i < q; ++i)

    {

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

        x--; y--;

        next[x] = y; pre[y] = x;

    }

    ll V = t;

    int v = 0;

    for (i = 0; i < n; ++i)

    {

        if (pre[i] == - 1)

        {

            v++;

            ll cur = a[i];

            j = i;

            while (next[j] != -1)

            {

                v++;

                V -= cur;

                j = next[j];

                cur += a[j];

                a[j] = cur;

            }

        }

    }

    if (V < 0 || v < n)

    {

        printf("0\n");

        return 0;

    }

    CL(f,0);

    f[0] = 1;

    for (i = 0; i < n; ++i)

    {

        for (j = a[i]; j <= V; ++j)

        {

            f[j] = (f[j] + f[j - a[i]])%mod;



        }

    }

    printf("%I64d\n",f[V]);



    return 0;

}

 

 

 

你可能感兴趣的:(codeforces)