zoukankan      html  css  js  c++  java
  • [SRM] 09 撕书狂魔CZL

    A. 撕书Ⅰ

    序列型DP。DP[i]表示当前编号结点的撕书页数。

    那么我们有 DP[ i ] = DP[ i - y - 1 ] + y

    其中y为编号i书页对应范围内的书页。

    那么,具体实现的话,需要求出每个i对应的y,这里用前缀和。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 #define maxn 1000005
     5 #define lowbit(x) (-x&x)
     6 using namespace std;
     7 
     8 int n,high = 0;
     9 
    10 struct node{
    11     int pos,ai;
    12 }list[maxn];
    13 
    14 int Tree[maxn],DP[maxn],minn;
    15 int sum(int p){
    16     int ans = 0;
    17     while(p){
    18 //        cout << '^';
    19 //        cout << p;
    20         ans += Tree[p];
    21         p -= lowbit(p);
    22     }
    23     return ans;
    24 }
    25 void add(int p){
    26     while(p <= high){
    27 //        cout << 'G';
    28         Tree[p]++;
    29         p += lowbit(p);
    30 //        cout << p;
    31     }
    32 }
    33 
    34 bool cmp(const node &a,const node &b){
    35     return a.pos < b.pos;
    36 }
    37 
    38 int main(){
    39     scanf("%d",&n);
    40     
    41     for(int i = 1;i <= n;i++){
    42         scanf("%d%d",&list[i].pos,&list[i].ai);
    43         list[i].pos++;
    44         high = max(high,list[i].pos);
    45     }
    46     
    47     sort(list+1,list+1+n,cmp);
    48     
    49 //    printf("#%d#
    ",high);
    50     
    51     for(int i = 1;i <= n;i++){
    52         
    53 //        cout << 'A';
    54         add(list[i].pos);
    55     }
    56     
    57     for(int i = 1;i <= n;i++){
    58         int a = list[i].pos-1;
    59         int b = list[i].pos-list[i].ai-1;
    60         if(a < 0) a = 0;
    61         if(b < 0) b = 0;
    62         int y = sum(a)-sum(b);
    63         if(i-y-1 < 0) continue;
    64         DP[i] = DP[i-y-1] + y;
    65     }
    66     
    67     minn = DP[n];
    68     
    69     for(int i = 1;i <= n;i++){
    70         minn = min(minn,DP[i]+n-i);
    71     }
    72     
    73     printf("%d",minn);
    74     
    75 //    cout << endl;
    76 //    for(int i = 0;i <= n;i++) printf("%d ",DP[i]);
    77     
    78 //    cout << endl;
    79 //    for(int i = 0;i <= 10;i++) printf("%d ",sum(i));
    80     
    81     return 0;
    82 }
    震惊!CYC的背景居然隐藏着这样的...

    B. 撕书 Ⅱ

    这道题略坑。

    x表示a+b,y表示a^b,那么我们定义一个z = (x-y)>> 1。

    这个z表示的就是有a+b进位的位(准确来说是a x b == 1)

    为什么呢?

    因为某些原因,异或等于没有进位的加,那么和就拥有异或结果所没有的进位的信息。

    和 - 异或 就可以去除其他冗余,得到进位的信息啦!

    然而需要右移一位才能精确表示。

    那么显然不合法的情况就包括:

      1. x < y :显然根据前文我们有 x ≥ y

      2. ( x - y ) & 1 != 0: ( x - y )>>1 表示有进位的二进制位,如果命题成立,-1位有进位是什么鬼??

    还有特殊情况:

      如果 x == y ,ans 需要减少2

      因为此时 a 和 b 可以有一个为0,所以需要排除这种情况。

    求解策略:

      如果 y 的一个二进制位为 1 ,显然 a 和 b 其中一个为 0 且另一个为 1 ,那么有两种情况,ans *= 2

      如果 y 的一个二进制位为 0 ,显然 a 和 b 的对应二进制位是相同的,ans *= 1

    以此检验 x 和 y 的每一位,ans也就出来了。

     1 #include<cstdio>
     2 #include<iostream>
     3 #define LL long long
     4 using namespace std;
     5 
     6 LL x,y,z,ans = 1;
     7 
     8 int main(){
     9     scanf("%lld%lld",&x,&y);
    10     
    11     z = x-y;
    12     
    13     if(z&1L || x < y){
    14         printf("0");
    15         return 0;
    16     }
    17     
    18     z >>= 1;
    19     
    20 //    for(LL i = 1;i <= x;i<<=1){
    21 //        printf("%d",(z&i)?1:0);.
    22 //    }
    23     
    24 //    cout << endl;
    25     
    26     for(LL a = 0;(1L<<a) <= x;a++){
    27 //        printf("%d",((1L<<a)&x)^((1L<<a)&z)?1:0);
    28         if(y&(1L<<a)){
    29             if(z&(1L<<a)){
    30 //                printf("*%lld*
    ",a);
    31 //                if((x&a) == (z&a)) cout << " dfdfdfd";
    32 //                cout << "#" << (x&a);
    33 //                cout << "#" << (z&a);
    34                 printf("0");
    35                 return 0;
    36             }
    37             
    38             ans *= 2;
    39         }
    40 //        if(y&a) ans *= 2;
    41     }
    42     
    43     if(x == y) ans -= 2;
    44     
    45     
    46     printf("%lld",ans);
    47     
    48     return 0;
    49 }
    题解比代码重要!

     

    转载请注明出处 -- 如有意见欢迎评论
  • 相关阅读:
    C++程序设计实验-3
    函数
    C++简单程序设计
    C++程序设计实验-2
    C++程序设计实验-1
    项目总结
    团队测试计划
    第二阶段团队绩效评分
    第二阶段scrum-10
    第二阶段scrum-9
  • 原文地址:https://www.cnblogs.com/Chorolop/p/7296615.html
Copyright © 2011-2022 走看看