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;
}

 

 

 

posted @ 2013-03-20 08:32  E_star  阅读(370)  评论(0编辑  收藏  举报