• 这种题应该诸位处理


    HDU 4588 Count The Carries

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4588

    求a~b求和在二进制情况下共发生多少次进位。

    1、将i转化成二进制,因为每一位只有出现多个1的时候才会产生进位。

    2、所以,统计每一位1的个数即可。

    3、统计1~b每一位1的个数,1~a-1中1的个数,作差即可。

        (对于怎么统计1~n的每一位1的个数,数学好的应该一眼能看出,数学不好的找找规律画画就行,不难的)

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 
     5 using namespace std;
     6 long long a, b;
     7 
     8 long long cal( long long b, long long a ){
     9     b++, a++;
    10     long long ans = 0;
    11     unsigned long long p = 2, k = 1;
    12     long long tmp = 0;
    13     for( int i = 0; i < 62; ++i ){
    14         long long cnt1_b = (b/p)*k;
    15         long long cnt1_a = (a/p)*k;
    16         if( b%p > k )
    17             cnt1_b += (b%p)-k;
    18         if( a%p > k )
    19             cnt1_a += (a%p)-k;
    20         long long cnt1 = cnt1_b - cnt1_a;
    21         ans += ( cnt1 + tmp )/2;
    22         tmp = ( cnt1 + tmp )/2;
    23         p *= 2, k *= 2;
    24     }
    25     //cout << "p:" << p << " k:" << k << endl;
    26 
    27     return ans;
    28 }
    29 
    30 int main(){
    31     while( scanf("%I64d%I64d", &a, &b) != EOF ){
    32         long long ans = cal( b, a-1 );
    33         printf("%I64d
    ", ans);
    34     }
    35 
    36     return 0;
    37 }
    View Code

    BNUOJ 24250 Binary Operations

    题目链接:http://www.bnuoj.com/v3/problem_show.php?pid=24250

    弱校联盟最后一场的B题。

    不难,但本人太弱,好在周爸比较机智。

    思路还是诸位处理,顶多32位。

    1、对于相&的情况,只有连续的1才有效,统计连续1的情况乘上改位权值即可。

    2、对于相|的情况,求反面,统计连续0的情况,再用总情况一减就行。

    3、对于异或,因为奇数个1会产生1,统计每个数到目前为止奇数个1和偶数个1的情况数,

        如果,改位为止有奇数个1,ans加上偶数个1的情况,还得加1,因为自身也合法;相反,加上奇数个1的情况。

       (这应该是处理连续子区间∑f(i,j)最常用的方法~)

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 
      5 using namespace std;
      6 const int maxn = 5e4 + 10;
      7 int bit[maxn][35], a[maxn];
      8 long long n;
      9 
     10 void change( int k, int p ){
     11     int cnt = 0;
     12     while(p){
     13         bit[k][cnt++] = p&1;
     14         p >>= 1;
     15     }
     16 }
     17 
     18 void input(){
     19     scanf("%lld", &n);
     20     memset( bit, 0, sizeof(bit) );
     21     for( int i = 1; i <= n; ++i ){
     22         scanf("%d", &a[i]);
     23         change( i, a[i] );
     24     }
     25 }
     26 
     27 void solve(){
     28     long long ans1 = 0;
     29     //与运算
     30     long long k = 1;
     31     for( int i = 0; i < 32; ++i ){
     32         long long cnt1 = 0;
     33         long long tmp = 0;
     34         for( int j = 1; j <= n; ++j ){
     35             while( j <= n && bit[j][i] == 1 ){
     36                 cnt1++;
     37                 j++;
     38             }
     39             tmp += cnt1*(cnt1+1)/2;
     40             cnt1 = 0;
     41         }
     42         ans1 += tmp * k, k *= 2;
     43     }
     44     //printf("%lld
    ", ans1);
     45 
     46     //或运算
     47     long long ans2 = 0;
     48     k = 1;
     49     for( int i = 0; i < 32; ++i ){
     50         long long cnt1 = 0;
     51         long long tmp = 0;
     52         for( int j = 1; j <= n; ++j ){
     53             while( j <= n && bit[j][i] == 0 ){
     54                 cnt1++;
     55                 j++;
     56             }
     57             tmp += cnt1*(cnt1+1)/2;
     58             cnt1 = 0;
     59         }
     60         ans2 += k*(n*(n+1)/2 - tmp), k *= 2;
     61     }
     62     //printf("%lld
    ", ans2);
     63 
     64     //异或运算
     65     long long ans3 = 0;
     66     k = 1;
     67     for( int i = 0; i < 32; ++i ){
     68         int ji = 0, ou = 0, tmp = 0;
     69         long long res = 0;
     70         for( int j = 1; j <= n; ++j ){
     71             if( bit[j][i] == 1 ){
     72                 tmp++;
     73             }
     74             if(tmp%2){
     75                 res += ou+1;
     76                 ji++;
     77             }else{
     78                 res += ji;
     79                 ou++;
     80             }
     81         }
     82         ans3 += res * k, k *= 2;
     83     }
     84 
     85     long long tot = n*(n+1)/2;
     86     printf(" %.6lf %.6lf %.6lf
    ", ans1/(1.0*tot), ans2/(1.0*tot), ans3/(1.0*tot) );
     87 }
     88 
     89 int main(){
     90     int T, cas = 1;
     91     scanf("%d", &T);
     92 
     93     while(T--){
     94         input();
     95         printf("Case #%d:", cas++);
     96         solve();
     97     }
     98 
     99     return 0;
    100 }
    View Code
  • 相关阅读:
    算法:二分图最大独立集
    算法:桶排序
    算法:二分图最小点覆盖——Konig定理
    jQuery基础整理之思维导图
    vue基础知识整理
    HTML总结
    JAVAScript总结
    栈和队列
    今日学习遇到的问题(2018.9.23)
    看了vue文档之后。。。。
  • 原文地址:https://www.cnblogs.com/zhazhalovecoding/p/4860377.html
Copyright © 2020-2023  润新知