zoukankan      html  css  js  c++  java
  • [SRM] 17

    qwq 怎么就17了

    A.

    对于待操作数列,所有的两个操作在宏观似乎都不会改变大体顺序

    (至于操作2交换奇偶位数字:奇偶分离就行了)

    那么定义 s1 s2 分别为奇数列和偶数列的起点(奇数和偶数自己是不会改变相对位置的)

    让 s1 s2 储存每次操作一的偏移量

    最后构造数列

     1 #include<cstdio>
     2 #include<iostream>
     3 #define maxn 1000000
     4 using namespace std;
     5 
     6 int ans[maxn],s1,s2,n,m,cnt,cnt2;
     7 
     8 int main(){
     9     scanf("%d%d",&n,&m);
    10     
    11     s1 = 1,s2 = 2;
    12     
    13     for(int i = 1;i <= m;i++){
    14         scanf("%d",&cnt);
    15         
    16         if(cnt%2){
    17             scanf("%d",&cnt2);
    18             s1 += cnt2;
    19             s2 += cnt2;
    20             if(s1 <= 0) s1 += n;
    21             if(s1 > n) s1 -= n;
    22             if(s2 <= 0) s2 += n;
    23             if(s2 > n) s2 -= n;
    24         }else{
    25             if(s1 % 2) s1++;
    26             else s1--;
    27             if(s2 % 2) s2++;
    28             else s2--;
    29         }
    30     }
    31     
    32     int i = s1,cnt = 1;
    33     while(!(i == s1 && cnt != 1)){
    34         ans[i] = cnt;
    35         i += 2;
    36         cnt += 2;
    37         if(i > n) i -= n;
    38     }
    39     
    40     i = s2,cnt = 2;
    41     while(!(i == s2 && cnt != 2)){
    42         ans[i] = cnt;
    43         i += 2;
    44         cnt += 2;
    45         if(i > n) i -= n;
    46     }
    47     
    48     for(int i = 1;i <= n;i++){
    49         printf("%d ",ans[i]);
    50     }
    51     
    52     return 0;
    53 } 
    A

    B.

    看了看CF的官方Editorial,二分原来是叫 Binary Search,学习了

    那么,二分k秒后的最小值和k秒后的最大值

    为了防止不会漏解把二分最大值嵌在二分最小值里

    http://codeforces.com/blog/entry/44821

    qwq感谢CZL的标程,写得非常对称!

     1 #include<cstdio>
     2 #include<iostream>
     3 #define maxn 1000000
     4 using namespace std;
     5 
     6 long long k,lowpool,uppool,cnt1,n,arr[maxn],maxx,minn = 0x3f3f3f3f,L,R,L2,R2,mid,ans = 0x3f3f3f3f;
     7 bool GG,GG2;
     8 
     9 int main(){
    10     scanf("%I64d%I64d",&n,&k);
    11     for(int i = 1;i <= n;i++){
    12         scanf("%I64d",&arr[i]);
    13         maxx = max(maxx,arr[i]),
    14         minn = min(minn,arr[i]);
    15     }
    16     
    17     L = minn,R = maxx;
    18     GG = false;
    19     while(!GG){
    20         mid = (L+R+1)/2;
    21         if(L == R) GG = true;
    22         lowpool = uppool = cnt1 = 0;
    23         
    24         for(int i = 1;i <= n;i++) lowpool += max(0,mid-arr[i]),uppool += max(0,arr[i]-mid),cnt1 += arr[i]<=mid;
    25         
    26         if(lowpool > k || lowpool >uppool){ R = mid-1; continue;}
    27         else L = mid;
    28         
    29         if(lowpool == uppool && lowpool <= k) return puts("0"),0;
    30         
    31         L2 = mid+1,R2 = maxx;
    32         
    33         cnt1 = min(k,cnt1-1+lowpool);
    34         
    35         GG2 = false;
    36         while(!GG2){
    37             mid = (L2+R2)/2;
    38             if(L2 == R2) GG2 = true;
    39             
    40             uppool = 0;
    41             for(int i = 1;i <= n;i++) uppool += max(arr[i]-mid,0);
    42             
    43             if(uppool > cnt1 || uppool > k){L2 = mid+1;continue;}
    44             else R2 = mid;
    45             
    46             ans = min(ans,mid-L);
    47         }
    48     }
    49     
    50     printf("%I64d",ans);
    51     
    52     return 0;
    53 }
    二分...

    C.

    只限定了树的直径和树的高

    那就简单了,最低限度满足条件即可

    首先画一条长度为D的多段线,那么一个典型的情况是:树根 1 在中点,将该多段线打折则每边的长度为 D/2

    这是临界点,此时树高为 H

    那么我们就知道了:如果 H * 2 < D 则必然无解(怎么打折都会有一边超过预测 H )

    那么我们只要在多段线上取一个点定为 1 就行了,接下来就是处理多余的结点(D+1 ~ n )

    (解释起来真复杂) 

    最简单的方法就是把多余节点一个个挂在深度第二的点当子节点

    (有那么点画同分异构体的感觉)

    既然这题的限制如此之少,又没有什么保证 既然这题出自CF

    就要往死里加特判,不要太相信自己程序的通用度

    特判见代码

     1 #include<cstdio>
     2 #include<iostream>
     3 using namespace std;
     4 
     5 int n,D,H,pre[1000000];
     6 
     7 int main(){
     8     scanf("%d%d%d",&n,&D,&H);
     9     
    10     if(H*2 < D || H > D || D == 1 || n-1 < D || n-1 < H) cout << -1;
    11     else{
    12         if(H < D){
    13             
    14             for(int i = 2;i <= H+1;i++){
    15                 pre[i] = i-1;
    16             }
    17             
    18             pre[H+2] = 1;
    19             for(int i = H+3;i <= D+1;i++){
    20                 pre[i] = i-1;
    21             }
    22             
    23             for(int i = 2;i <= n;i++){
    24                 if(!pre[i]) pre[i] = H;
    25             }
    26             
    27         }else{
    28             
    29             for(int i = 2;i <= H+1;i++){
    30                 pre[i] = i-1;
    31             }
    32             
    33             for(int i = 2;i <= n;i++){
    34                 if(!pre[i]) pre[i] = H;
    35             }
    36             
    37         }
    38         for(int i = 2;i <= n;i++)
    39         printf("%d %d
    ",pre[i],i);
    40     }
    41     
    42     
    43     
    44     return 0;
    45 } 
    重构代码把D == 1给忘了然后就FST了qwq
    转载请注明出处 -- 如有意见欢迎评论
  • 相关阅读:
    微信开发笔记:修改公众号自定义菜单
    微信开发笔记:公众号获取access_token
    微信开发笔记:微信浏览器分享设置以及回调
    HTML5开发笔记:初窥CANVAS,上传canvas图片到服务器
    求解分组问题(百度面试题)
    Python求解啤酒问题(携程2016笔试题)
    Fiddler教程【转】
    求解朋友关系中的朋友圈数量
    HTTP协议详解【转】
    求解暗黑字符串(网易2017秋招)
  • 原文地址:https://www.cnblogs.com/Chorolop/p/7469409.html
Copyright © 2011-2022 走看看