http://codeforces.com/contest/284
A:快速幂取模,套上模板枚举就行。当时脑子乱了,竟然想超数据类型了不行啊,快速幂取模就可以解决的。
B:大水题,很多人估计AB两题搞倒了。
C:线段树维护区间添加,单点询问,O(Nlog(n))做。当时做的时候直接把模板弄了过来结果中间有个错误,一直调啊调,到了最后才发现,超级郁闷。
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;
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
思路:
乍一看是完全背包,可是怎样保证这样的数量关系呢。不好搞,后来看看别人的代码,超级给力,我们只要记录每个比他数量大的,然后添加一个自己就相当于所有比他大的都要添加一个,所以我们要把比他大的的值都加到他身上,然后添加时。就按照完全背包做就好了,这样就保证了添加进去的肯定满足数量关系。
#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; }