• 题解 UVa11645


    题目大意 多组数据,每组数据给定一个正整数 (n),请求出 (sum_{i=0}^n A(i)),其中 (A(n))(n) 的二进制表示中连续两个 (1) 出现的个数(比如 (A(6_{10})=A(110_2)=2,A(15_{10})=A(1111_2)=3)),输入以负整数结尾。

    分析 正面统计很难做,所以我们从反面来统计每组相邻的 (1) 会给答案做出多少贡献。不难发现,这两位做出的贡献就是其在二进制表示下前面的部分加上一个零头。而这个零头仅在这两位本来就是 (1) 的时候才会出现,且就是这两位后面的部分(比如 (11101_2) 中第 (3,4) 两位的贡献为 ((11000+0)_2)(2,3) 位的贡献为 ((10000+01)_2))。

    比较恶心的是这道题输入不是以 (-1) 结尾,而是负整数,且最大的数据会爆 long long,只能手写高精度或使用 __int128

    #include<bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    
    int t;
    __int128 n, x, now, ans;
    
    
    __int128 Read()
    {
    	__int128 x = 0, op = 1;
    	char ch = getchar();
    	while(ch < '0' || ch > '9') {
    		if(ch == '-') op = -1;
    		ch = getchar();
    	}
    	while(ch >= '0' && ch <= '9') {
    		x = (x << 3) + (x << 1) + ch - '0';
    		ch = getchar();
    	}
    	return x * op;
    }
    
    void Print(__int128 x)
    {
    	if(x < 0) putchar('-1'), x = -x;
    	if(x > 9) Print(x / 10);
    	putchar(x % 10 + '0');
    }
    
    int main()
    {
    	while((n = Read()) >= 0) {
    		ans = 0, now = 0, x = n;
    		while(x) {
    			ans += ((__int128)1 << now) * (x >> 2) + (x & 1 && x & 2) * (n % ((__int128)1 << now) + 1);
    			x >>= 1, ++now;
    		}
    		printf("Case %d: ", ++t);
    		Print(ans), putchar('
    ');
    	}
    }
    
  • 相关阅读:
    request内置对象
    JSP页面、包含
    HTTP协议
    html简介
    数据访问层工具类
    数据运算
    可变于不可变对象分类
    有序 无序 的区别
    字符串方法
    day01_final
  • 原文地址:https://www.cnblogs.com/whx1003/p/12323367.html
Copyright © 2020-2023  润新知