题目:http://codeforces.com/contest/834/problem/C
题意:两个人玩游戏, 两个人初始值都为1,每次可以选一个正整数,一个人乘以这个正整数的平方,一个人乘以这个正整数,给你多对数<a,b>,判断会不会出现这个游戏局面
把ab乘起来,判断是不是一个数的三次方,并且是不是能被a和b整除
k^3==a*b&&a%k==0&&b%k==0
结果找k的二分写错了。。。。。。。改了半天,,还好过了
举个会出现的游戏局面的例子
a=a1 * a2 * a3^3 * a4 = (a1*a2*a3*a4) * a3
b=a1^2 * a2^2 * a3 * a4^2 = (a1*a2*a3*a4) * (a1*a2*a4)
其中(a1*a2*a3*a4) 也就是k
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50#include<bits/stdc++.h> #define eps 1e-9 #define PI 3.141592653589793 #define bs 1000000007 #define bsize 256 #define MEM(a) memset(a,0,sizeof(a)) typedef long long ll; using namespace std; int ask(long long x) { long long le=1,ri=1e6; long long mid; while(le<ri) { mid=(le+ri)>>1; long long now=mid*mid*mid; if(now==x) return mid; else if(le*le*le==x) return le; else if(ri*ri*ri==x) return ri; else if(now<x) le=mid+1; else ri=mid; } return 0; } int main() { int n; long long a,b; cin>>n; while(n--) { scanf("%lld %lld",&a,&b); long long now=ask(a*b); if(now) { if(a%now==0&&b%now==0) printf("Yesn"); else printf("Non"); } else printf("Non"); } return 0; }
D:http://codeforces.com/contest/834/problem/D
题意:给一段序列,分成k个段连续的序列,每段序列的值为这段序列不同的数的个数,求最大的k个序列值的和
做法参考自:http://blog.csdn.net/ssimple_y/article/details/76410328
dp加线段树优化,dp【i】【j】表示前i个数字分成j个部分得到的最大的和
dp【i】【j】=max(dp【t】【j-1】+dif【t+1】【i】)dif【i】【i】表示i到j段不同数字的个数,正常转移会t
这里用线段树优化,具体看代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84#include<bits/stdc++.h> using namespace std; int n,k,cot=0; const int maxn=40000; int a[maxn],book[maxn],pre[maxn],lazy[4*maxn],seg[4*maxn]; int dp[maxn][55]; void pushback(int node) { seg[node]=max(seg[node<<1],seg[node<<1|1]); return ; } void pushdown(int node) { if(lazy[node]) { seg[node<<1]+=lazy[node]; lazy[node<<1]+=lazy[node]; seg[node<<1|1]+=lazy[node]; lazy[node<<1|1]+=lazy[node]; lazy[node]=0; } return ; } void update(int le,int ri,int k,int l,int r,int node) { if(le<=l&&ri>=r) { seg[node]+=k; lazy[node]+=k; return ; } pushdown(node); int m=(l+r)>>1; if(m>=le) update(le,ri,k,l,m,node<<1); if(ri>m) update(le,ri,k,m+1,r,node<<1|1); pushback(node); return ; } int query(int le,int ri,int l,int r,int node) { if(le<=l&&ri>=r) { return seg[node]; } pushdown(node); int m=(l+r)>>1; int ans=0; if(m>=le) ans=max(query(le,ri,l,m,node<<1),ans); if(m<ri) ans=max(query(le,ri,m+1,r,node<<1|1),ans); // pushback(node); return ans; } int main() { cin>>n>>k; int i,j; for(i=1;i<=n;i++) { scanf("%d",&a[i]); pre[i]=book[a[i]];//记录相同的数最后一次出现的位置保证了相同的数只能对一个位置加一次 book[a[i]]=i; } for(i=1;i<=k;i++) { memset(seg,0,sizeof(seg)); memset(lazy,0,sizeof(lazy)); for(j=1;j<=n;j++) { update(j,j,dp[j][i-1],0,n,1);//先给节点加上一个dp【t】【j-1】的初值 } for(j=i;j<=n;j++) { update(max(i-1,pre[j]),j-1,1,0,n,1);//dif【t+1】【i】这部分并不好直接求,直接加,所以可以反向考虑, dp[j][i]=query(i-1,j-1,0,n,1); } } cout<<dp[n][k]<<endl; }
最后
以上就是柔弱帆布鞋最近收集整理的关于Codeforces Round #426 (Div. 2) C. The Meaningless Game 思维 D. The Bakery dp的全部内容,更多相关Codeforces内容请搜索靠谱客的其他文章。
发表评论 取消回复