新的一周>_<
---12.14
补之前的一场 cf
cf 604c
http://codeforces.com/contest/604/problem/C
给一串长度为 n 的 01串,可以翻转一个区间,问能够得到的最长的01序列是多长(可以不连续)
没有想出来,,,
其实可以发现,翻转一个区间,能够给原串带来2个贡献,所以算出原来的最长的加上 2 和 n 取最小值就好了
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<vector> 6 using namespace std; 7 8 const int maxn = 1e5+5; 9 char s[maxn]; 10 int n; 11 12 void solve(){ 13 int c = 0; 14 for(int i = 1;i <= n;){ 15 c++; 16 int j = i; 17 while(j <= n && s[i] == s[j]) j++; 18 i = j; 19 } 20 int ans = 0; 21 ans = min(c+2,n); 22 printf("%d\n",ans); 23 } 24 25 int main(){ 26 while(scanf("%d",&n) != EOF){ 27 scanf("%s",s+1); 28 solve(); 29 } 30 return 0; 31 }
---12.15
cf 318 c
http://codeforces.com/problemset/problem/318/C
给出两个数 x,y ,再给出一个 m ,每次操作可以用 x+y 去替换掉 x , y 中的一个更小的数,
问至少需要多少次操作,使得这两个数中至少有一个大于等于m
一开始就是想的,用 x+y 去代替(x,y) 里面的更小的,然后一直while循环到大于等于m
然后又wa又t的- -
是漏掉了 x < 0 && y > 0,这种应该先直接算出 x 需要多少次变成正的
然后还t了,,,是因为计数那个cnt也会爆int
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<iostream> 5 #include<algorithm> 6 #include<vector> 7 using namespace std; 8 9 typedef long long LL; 10 const int maxn = 1e6+5; 11 LL a[maxn]; 12 LL x,y,m; 13 14 void solve(){ 15 if(x >= m || y >= m){ 16 puts("0"); 17 return; 18 } 19 if(x < m && y < m && x <= 0 && y <= 0){ 20 puts("-1"); 21 return; 22 } 23 if(x > y) swap(x,y); 24 LL dayu0; 25 int flag = 0; 26 if(x < 0 && y > 0){ 27 int ret = 0; 28 dayu0 = (-x)/y; 29 if((-x)%y) dayu0++; 30 x = x + 1LL*dayu0*y; 31 // printf("x = %I64d dayu0 = %I64d\n",x,dayu0); 32 flag = 1; 33 } 34 LL c = y; 35 LL cnt = 0; 36 while(c < m){ 37 c = x+y; 38 x = y; 39 y = c; 40 if(x > y) swap(x,y); 41 cnt++; 42 } 43 if(flag) printf("%I64d\n",cnt+dayu0); 44 else printf("%I64d\n",cnt); 45 } 46 47 int main(){ 48 while(scanf("%I64d %I64d %I64d",&x,&y,&m) != EOF){ 49 solve(); 50 } 51 return 0; 52 }
补个bc
hdu 5596 GTW likes gt
比赛的时候用树状数组写的,,,一直调不对,,,后来又想不通这个做法了,,,
看的题解的O(n) 的做法写的
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<vector> 6 using namespace std; 7 8 const int maxn = 5e5+5; 9 int a[maxn],b[maxn],c[maxn]; 10 int cnt[maxn]; 11 int n,m; 12 13 void solve(){ 14 int mx0 = -1,mx1 = -1; 15 int l = 0; 16 for(int i = n;i >= 1;i--){ 17 if(cnt[i]) { 18 mx1 -= cnt[i]; 19 mx0 -= cnt[i]; 20 } 21 if(a[i] == 0){ 22 if(mx1 >= b[i]) l++; 23 mx0 = max(mx0,b[i]); 24 } 25 else{ 26 if(mx0 >= b[i]) l++; 27 mx1 = max(mx1,b[i]); 28 } 29 } 30 printf("%d\n",n-l); 31 } 32 33 int main(){ 34 int T; 35 scanf("%d",&T); 36 while(T--){ 37 scanf("%d %d",&n,&m); 38 memset(cnt,0,sizeof(cnt)); 39 for(int i = 1;i <= n;i++) scanf("%d %d",&a[i],&b[i]); 40 for(int i = 1;i <= m;i++) { 41 scanf("%d",&c[i]); 42 cnt[c[i]]++; 43 } 44 solve(); 45 } 46 return 0; 47 }
今天焊成了 “趣味闪灯”,,,不过不知道通电之后会不会闪阿,,,好惶恐---
---12.16
hdu 5597 GTW likes function
题解说的打表,,,
证明还没有看---
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<iostream> 5 #include<algorithm> 6 using namespace std; 7 8 typedef long long LL; 9 LL n,x; 10 11 LL euler(LL v){ 12 LL k = sqrt(1.0*v); 13 LL res = v; 14 for(LL i = 2;i <= k;i++) if(v%i == 0){ 15 while(v%i == 0) v /= i; 16 res = res/i*(i-1); 17 } 18 if(v > 1) res = res/v*(v-1); 19 return res; 20 } 21 22 int main(){ 23 while(scanf("%I64d %I64d",&n,&x) != EOF){ 24 printf("%I64d\n",euler(n+x+1)); 25 } 26 return 0; 27 }
---12.17
补个cf 335 div2
这场 cf 打得太挫----默默跌绿---
cf 606 a
http://codeforces.com/contest/606/problem/A
感觉自己想复杂了,而且因为自己是乘以 2来算的,
一直 wa 8
因为是 两个相同颜色的可以换一个别的颜色的,所以应该直接除以2来算
贴一下代码,,纪念下自己的sb - -
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<vector> 5 using namespace std; 6 7 typedef long long LL; 8 const int maxn = 1e6+5; 9 int n,m; 10 int a,x[15],used[15]; 11 int b,c; 12 13 void solve(){ 14 if(a < x[1] && b < x[2] && c < x[3]){ 15 puts("No"); 16 return; 17 } 18 if(a >= x[1] && b >= x[2] && c >= x[3]){ 19 puts("Yes"); 20 return; 21 } 22 23 int cnt = 0; 24 if(a < x[1]){ 25 int need = x[1]-a; 26 //need = need; 27 int cb = (x[2]-b)/2; 28 int cc = (x[3]-c)/2; 29 cb = -cb,cc = -cc; 30 if(cb >= need){ 31 cnt++; 32 b-= need*2; 33 } 34 else if(cc >= need){ 35 cnt++; 36 c-= need*2; 37 } 38 else if((cb + cc) >= need){ 39 cnt++; 40 int t = b-x[2]; 41 b = x[2]; 42 c -= (need*2-t); 43 } 44 else{ 45 puts("No"); 46 return; 47 } 48 } 49 else cnt++; 50 51 if(b < x[2]){ 52 int need = x[2]-b; 53 // need = need; 54 int ca = (x[1]-a)/2; 55 int cc = (x[3]-c)/2; 56 ca = -ca,cc = -cc; 57 // printf("ca = %d cc = %d\n",ca,cc); 58 if(ca >= need){ 59 cnt++; 60 a-= need*2; 61 } 62 else if(cc >= need){ 63 cnt++; 64 c-= need*2; 65 } 66 else if((ca + cc) >= need){ 67 cnt++; 68 int t = x[1]-a;t = -t; 69 a = x[1]; 70 c -= (need*2-t); 71 } 72 else{ 73 puts("No"); 74 return; 75 } 76 } 77 else cnt++; 78 79 // printf("a = %d b = %d c = %d\n",a,b,c); 80 81 if(c < x[3]){ 82 int need = x[3]-c; 83 // need = need*2; 84 int ca = (x[1]-a)/2; 85 int cb = (x[2]-b)/2; 86 ca = -ca,cb = -cb; 87 // printf("ca = %d cb = %d\n",ca,cb); 88 if(ca >= need){ 89 cnt++; 90 a-= need*2; 91 } 92 else if(cb >= need){ 93 cnt++; 94 b-= need*2; 95 } 96 else if((ca + cb) >= need){ 97 cnt++; 98 int t = x[1]-a;t=-t; 99 a = x[1]; 100 b -= (2*need-t); 101 } 102 else{ 103 puts("No"); 104 return; 105 } 106 } 107 else cnt++; 108 if(cnt == 3) puts("Yes"); 109 else puts("No"); 110 111 } 112 113 int main(){ 114 while(scanf("%d %d %d",&a,&b,&c) != EOF){ 115 scanf("%d %d %d",&x[1],&x[2],&x[3]); 116 // b = a[2],c = a[3]; 117 solve(); 118 } 119 return 0; 120 }
cf 606 b
比赛的时候看过的人少,没有看- -
读懂题就好了
cf 606 c
sb 地想都没想 直接 n-LIS 结果居然过了初测---
应该是 dp[i] 表示以 i 结尾 的最长的连续的序列的长度
然后是 n - max(dp[i])
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<vector> 5 #include<cstring> 6 using namespace std; 7 8 const int maxn = 1e6+5; 9 int a[maxn],dp[maxn],n; 10 11 void solve(){ 12 memset(dp,0,sizeof(dp)); 13 dp[a[1]] = 1; 14 for(int i = 2;i <= n;i++){ 15 dp[a[i]] = dp[a[i]-1]+1; 16 // printf("dp[%d] = %d\n",a[i],dp[a[i]]); 17 } 18 int ans = 0; 19 for(int i = 1;i <= n;i++) ans = max(ans,dp[i]); 20 printf("%d\n",n-ans); 21 } 22 23 int main(){ 24 while(scanf("%d",&n) != EOF){ 25 for(int i = 1;i <= n;i++) scanf("%d",&a[i]); 26 solve(); 27 } 28 return 0; 29 }
cf 606 d
构造一棵菊花树,然后依次向上面加图边
加边的顺序搞不清楚,wa 到死
后来问了一神
因为构造树 的时候 加边 是
1--2,1--3,1--4,---,1--n;这样
然后加图边的时候,如果是
2--3,2--4,2--5,---,2--n
那么在 加 1-- n 这条边之前,就已经加了 2-- n这条边了
2--n 这条边 比 1--n 这条边 短
这样,就应该选择 2--n这条边,而不是构造的 1--n那条边,就不行了
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<iostream> 5 #include<algorithm> 6 #include<vector> 7 using namespace std; 8 9 typedef long long LL; 10 const int maxn = 1e6+5; 11 int n,m; 12 struct Edge{ 13 int a,b; 14 int id; 15 }e[2*maxn]; 16 int vis1[maxn]; 17 int vis2[maxn]; 18 19 Edge ans[2*maxn]; 20 21 int cmp(Edge n1,Edge n2){ 22 if(n1.a != n2.a) return n1.a < n2.a; 23 return n1.b > n2.b; 24 } 25 26 int cmp1(Edge n1,Edge n2){ 27 return n1.id < n2.id; 28 } 29 30 void solve(){ 31 memset(vis1,0,sizeof(vis1)); 32 memset(vis2,0,sizeof(vis2)); 33 int shul = 1,shur = 1; 34 int tul = 2,tur = 2; 35 int u,v; 36 sort(e+1,e+m+1,cmp); 37 38 /* printf("---begin---\n"); 39 for(int i = 1;i <= m;i++){ 40 printf("---%d %d\n",e[i].a,e[i].b); 41 } 42 printf("---end---\n");*/ 43 LL c1 = 0,c2 = 0; 44 for(int i = 1;i <= m;i++){ 45 if(e[i].b == 1){ 46 u = 1; 47 shul++; 48 v = shul; 49 c1++; 50 ans[i].a = u;ans[i].b = v;ans[i].id = e[i].id; 51 } 52 else c2++; 53 if(c1*(c1-1)/2 < c2){ 54 puts("-1"); 55 return; 56 } 57 } 58 59 /* for(int i = 1;i <= m;i++){ 60 printf("ans[%d].a = %d ans[%d].b = %d \n",i,ans[i].a,i,ans[i].b); 61 }*/ 62 63 int cnt = 1; 64 // printf("shul = %d\n",shul); 65 for(int i = 3;i <= shul;i++){ 66 if(cnt > m) break; 67 for(int j = 2;j < i;j++){ 68 // printf("----i = %d j = %d cnt = %d\n",i,j,cnt); 69 while(e[cnt].b) cnt++; 70 ans[cnt].a = i; 71 ans[cnt].b = j; 72 ans[cnt].id = e[cnt].id; 73 cnt++; 74 // printf("---i = %d j = %d cnt = %d\n",i,j,cnt); 75 // break; 76 } 77 } 78 79 sort(ans+1,ans+m+1,cmp1); 80 for(int i = 1;i <= m;i++){ 81 printf("%d %d\n",ans[i].a,ans[i].b); 82 } 83 } 84 85 int main(){ 86 while(scanf("%d %d",&n,&m) != EOF){ 87 for(int i = 1;i <= m;i++){ 88 scanf("%d %d",&e[i].a,&e[i].b); 89 e[i].id = i; 90 } 91 solve(); 92 } 93 return 0; 94 }
---12.18
cf 305 c
http://codeforces.com/problemset/problem/305/C
给出 n 个数,a1,a2,a3,---,an
问至少加入几个数,b1,b2,---,bm
使得 2^a1 + 2^a2 + --- + 2^an + 2^b1 + 2^b2 + --- + 2^bm 的和为 2 ^v -1(v为一个整数)
因为 是 2^v-1的话,转化成二进制,它的每一位都是 1
然后最开始的想法是,统计每一个相同的ai 的个数,换成 尽可能多的数
然后就看从 0 1 2 到 最大的那个数中间少几个,就加几个
可是是错的,,不知道为什么是错的--
然后,就像貌似是10月份的一场cf的一题那样,
如果队列里面取出 的 x ,y
x == y,就进位 x+1放进去
x != y,不进位,再把y放进去
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<queue> 6 #include<vector> 7 using namespace std; 8 9 const int maxn = 1e5+5; 10 int a[maxn],n; 11 12 void solve(){ 13 priority_queue<int,vector<int> ,greater<int> > q; 14 for(int i = 1;i <= n;i++) q.push(a[i]); 15 int ed = -1; 16 int x,y; 17 vector<int> c; 18 while(!q.empty()){ 19 x = q.top();q.pop(); 20 ed = max(ed,x); 21 if(q.empty()) { 22 c.push_back(x); 23 break; 24 } 25 y = q.top();q.pop(); 26 ed = max(ed,y); 27 if(x != y) { 28 c.push_back(x); 29 q.push(y); 30 } 31 else q.push(x+1); 32 } 33 // printf("ed = %d\n",ed); 34 printf("%d\n",ed+1-c.size()); 35 } 36 37 int main(){ 38 while(scanf("%d",&n) != EOF){ 39 for(int i = 1;i <= n;i++) scanf("%d",&a[i]); 40 solve(); 41 } 42 return 0; 43 }
---12.19
做了第一次 cf 的educational round
---12.20
cf 304 c
http://codeforces.com/problemset/problem/304/C
给出 n,然后构造三个序列 a,b,c
使得对于任意 的 (a[i] + b[i])% n == (c[i] % n)
打表找规律
发现偶数构造不出来,奇数按照
0 2 4 --- 1 3 ---
0 n-1 n-2 --- 2 1这样来放
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 7 const int maxn = 1e5+5; 8 int a[maxn],b[maxn],c[maxn]; 9 int n; 10 11 void solve(){ 12 if(n%2 == 0){ 13 puts("-1"); 14 return; 15 } 16 for(int i = 0;i < n;i++) c[i] = i; 17 a[0] = 0; 18 for(int i = 1;i <= n/2;i++){ 19 a[i] = i*2; 20 a[i+n/2] = i*2-1; 21 } 22 b[0] = 0; 23 for(int i = 1;i < n;i++){ 24 b[i] = n-i; 25 } 26 for(int i = 0;i < n;i++) printf("%d ",a[i]); 27 printf("\n"); 28 for(int i = 0;i < n;i++) printf("%d ",b[i]); 29 printf("\n"); 30 for(int i = 0;i < n;i++) printf("%d ",c[i]); 31 printf("\n"); 32 } 33 34 int main(){ 35 while(scanf("%d",&n) != EOF){ 36 solve(); 37 } 38 return 0; 39 }