CF #275 div2

2014-10-25 04:02:59

搞了三题,D题想到是线段树,有点思路。。。但最后没敲出来。

A题:根据相邻两数互质,相邻奇数互质,判断一下

  (1)l为奇数,那么r至少比大3。因为l=3,r=5,取3,4,5不符合;但l=3,r=6,取4,5,6就符合。那么l+1,l+2,l+3符合条件。

  (2)l为偶数,那么l,l+1,l+2符合条件。

 1 /*************************************************************************
 2     > File Name: a.cpp
 3     > Author: Nature
 4     > Mail: 564374850@qq.com 
 5     > Created Time: Sat 25 Oct 2014 12:59:51 AM CST
 6 ************************************************************************/
 7 
 8 #include <cstdio>
 9 #include <cstring>
10 #include <cstdlib>
11 #include <cmath>
12 #include <vector>
13 #include <map>
14 #include <set>
15 #include <stack>
16 #include <queue>
17 #include <iostream>
18 #include <algorithm>
19 using namespace std;
20 #define lp (p << 1)
21 #define rp (p << 1|1)
22 #define getmid(l,r) (l + (r - l) / 2)
23 #define MP(a,b) make_pair(a,b)
24 typedef long long ll;
25 const int INF = 1 << 30;
26 
27 ll l,r;
28 
29 int main(){
30     scanf("%I64d%I64d",&l,&r);
31     if(l % 2){
32         if(r - l <= 2)
33             printf("-1\n");
34         else
35             printf("%I64d %I64d %I64d\n",l + 1,l + 2,l + 3);
36     }
37     else{
38         if(r - l <= 1)
39             printf("-1\n");
40         else
41             printf("%I64d %I64d %I64d\n",l,l + 1,l + 2);
42     }
43     return 0;
44 }
View Code

 

B题:二分答案,然后判断即可。要注意一下一个容斥的现象。

  因为x,y互质,所以1,2,....,v中x的倍数可以给first friend,y的倍数可以给second friend,但是注意1,2,...,v中x*y的倍数不可以给first or second friend。

  去掉这些数后,1,2,....,v中还剩:v - v/y - v/x + v/(x*y) 个数。

  所以只要判断一下 v - v/y - v/x + v/(x*y) >= c1 + c2 ,【 c1 = max(0,cnt1 - v/y + v/(x*y)) , c2 = max(0,cnt2 - v/x + v/(x*y))】

 1 /*************************************************************************
 2     > File Name: b.cpp
 3     > Author: Nature
 4     > Mail: 564374850@qq.com 
 5     > Created Time: Sat 25 Oct 2014 01:17:10 AM CST
 6 ************************************************************************/
 7 
 8 #include <cstdio>
 9 #include <cstring>
10 #include <cstdlib>
11 #include <cmath>
12 #include <vector>
13 #include <map>
14 #include <set>
15 #include <stack>
16 #include <queue>
17 #include <iostream>
18 #include <algorithm>
19 using namespace std;
20 #define lp (p << 1)
21 #define rp (p << 1|1)
22 #define getmid(l,r) (l + (r - l) / 2)
23 #define MP(a,b) make_pair(a,b)
24 typedef long long ll;
25 const int INF = 1 << 30;
26 
27 ll cnt1,cnt2,x,y;
28 
29 bool Solve(ll v){
30     ll vx,vy,vxy;
31     vx = v / x;
32     vy = v / y;
33     vxy = v / (x * y);
34     ll c1 = cnt1 - vy + vxy;
35     if(c1 < 0) c1 = 0;
36     ll c2 = cnt2 - vx + vxy ;
37     if(c2 < 0) c2 = 0;
38     if(v - vx - vy + vxy >= c1 + c2)
39         return true;
40     return false;
41 }
42 
43 int main(){
44     scanf("%I64d %I64d %I64d %I64d",&cnt1,&cnt2,&x,&y);
45     ll mid,ans,l = 1,r = (ll)20000000000010;
46     while(l < r){
47         mid = getmid(l,r);
48         if(Solve(mid)){
49             ans = mid;
50             r = mid;
51         }
52         else l = mid + 1;
53     }
54     printf("%I64d\n",ans);
55     return 0;
56 }
View Code

 

C题:我们发现:1,n,2,n-1,3,n-2......这个序列每两个相邻数差均不一样,为n-1,n-2,n-3...1,所以基于这个我们就可以构造序列了。

 1 /*************************************************************************
 2     > File Name: c.cpp
 3     > Author: Nature
 4     > Mail: 564374850@qq.com 
 5     > Created Time: Sat 25 Oct 2014 01:55:23 AM CST
 6 ************************************************************************/
 7 
 8 #include <cstdio>
 9 #include <cstring>
10 #include <cstdlib>
11 #include <cmath>
12 #include <vector>
13 #include <map>
14 #include <set>
15 #include <stack>
16 #include <queue>
17 #include <iostream>
18 #include <algorithm>
19 using namespace std;
20 #define lp (p << 1)
21 #define rp (p << 1|1)
22 #define getmid(l,r) (l + (r - l) / 2)
23 #define MP(a,b) make_pair(a,b)
24 typedef long long ll;
25 const int INF = 1 << 30;
26 
27 int main(){
28     int n,k;
29     scanf("%d%d",&n,&k);
30     int f = 1,p1 = 1,p2 = n;
31     while(k > 1){
32         if(f == 1){
33             printf("%d ",p1);
34             ++p1;
35         }
36         else{
37             printf("%d ",p2);
38             --p2;
39         }
40         --k;
41         f = 3 - f;
42     }
43     if(f == 2)
44         for(int i = p2; i >= p1; --i)    printf("%d ",i);
45     else
46         for(int i = p1; i <= p2; ++i)    printf("%d ",i);
47     puts("");
48     return 0;
49 }
View Code

 

D题:线段树题,每个条件可以看做区间更新,给每个节点一个cover值,更新到就或上更新的值。因为对每个操作l,r,q,将[l,r]上每个值或上q,相当于建立一条路,q从l一直&到r,都是通的,根据这个思想,就把问题区间更新。最后判断的话,对每个操作进行一次查询,模拟&的过程。

 1 /*************************************************************************
 2     > File Name: d.cpp
 3     > Author: Nature
 4     > Mail: 564374850@qq.com 
 5     > Created Time: Sat 25 Oct 2014 02:20:37 AM CST
 6 ************************************************************************/
 7 
 8 #include <cstdio>
 9 #include <cstring>
10 #include <cstdlib>
11 #include <cmath>
12 #include <vector>
13 #include <map>
14 #include <set>
15 #include <stack>
16 #include <queue>
17 #include <iostream>
18 #include <algorithm>
19 using namespace std;
20 #define lp (p << 1)
21 #define rp (p << 1|1)
22 #define getmid(l,r) (l + (r - l) / 2)
23 #define MP(a,b) make_pair(a,b)
24 typedef long long ll;
25 const int INF = 1 << 30;
26 const int maxn = 100010;
27 const int top = 2147483647;
28 
29 int n,m;
30 int li[maxn],ri[maxn],qi[maxn];
31 int pos[maxn];
32 
33 struct node{
34     int cover;
35 }t[maxn << 2];
36 
37 void Build_tree(int p,int l,int r){
38     memset(t,0,sizeof(t));
39 }
40 
41 void Push_down(int p){
42     t[lp].cover |= t[p].cover;
43     t[rp].cover |= t[p].cover;
44 }
45 
46 void Update_tree(int a,int b,int c,int p,int l,int r){
47     if(a <= l && r <= b){
48         t[p].cover |= c;
49         return;
50     }
51     int mid = getmid(l,r);
52     //Push_down(p);
53     if(a <= mid) Update_tree(a,b,c,lp,l,mid);
54     if(b > mid) Update_tree(a,b,c,rp,mid + 1,r);
55 }
56 
57 int Query_tree(int a,int b,int p,int l,int r){
58     if(a <= l && r <= b)
59         return t[p].cover;
60     Push_down(p);
61     int res = top;
62     int mid = getmid(l,r);
63     if(a <= mid)    res &= Query_tree(a,b,lp,l,mid);
64     if(b > mid)     res &= Query_tree(a,b,rp,mid + 1,r);
65     return res;
66 }
67 
68 void Print(int p,int l,int r,int val){
69     if(l == r){
70         printf("%d ",val | t[p].cover);
71         return;
72     }
73     int mid = getmid(l,r);
74     Print(lp,l,mid,val | t[p].cover);
75     Print(rp,mid + 1,r,val | t[p].cover);
76 }
77 
78 int main(){
79     scanf("%d%d",&n,&m);
80     Build_tree(1,1,n);
81     for(int i = 1; i <= m; ++i){
82         scanf("%d%d%d",&li[i],&ri[i],&qi[i]);
83         Update_tree(li[i],ri[i],qi[i],1,1,n);
84     }
85     for(int i = 1; i <= m; ++i){
86         if(Query_tree(li[i],ri[i],1,1,n) != qi[i]){
87             printf("NO\n");
88             return 0;
89         }
90     }
91     printf("YES\n");
92     Print(1,1,n,0);
93     puts("");
94     return 0;
95 }
View Code

 

posted @ 2014-10-25 13:20  Naturain  阅读(184)  评论(0)    收藏  举报