位运算很好的一个性质是可以单独每一位考虑。。。。。

题解请看:http://blog.csdn.net/skywalkert/article/details/45401245

对于异或的和,先枚举位,求所有异或和和中该位为1的有多少个,再乘以该位的大小(2的多少次方)。

即单独每一位考虑,每位带的权不一样。

对于和的异或,只需知道每一位中和的改位为1的奇偶性,就可以知道最终的异或值上该位是0还是1。

也是单独考虑每一位,看该位为0或1的条件。

 /**************************************************************
Problem: 4017
User: idy002
Language: C++
Result: Accepted
Time:9896 ms
Memory:3544 kb
****************************************************************/ #include <cstdio>
#include <cstring>
#include <algorithm>
#define N 100010
#define Mod 998244353
using namespace std; typedef long long dnt; int n;
int aa[N]; namespace Task1 {
dnt ans;
int cnt[];
dnt mpow( dnt a, int b ) {
dnt rt;
for( rt=; b; b>>=,a=a*a%Mod )
if( b& ) rt=rt*a % Mod;
return rt;
}
void main() {
for( int b=; b<=; b++ ) {
cnt[] = cnt[] = ;
for( int i=; i<=n; i++ ) {
int bb = (aa[i]>>b)&;
int c0 = cnt[];
int c1 = cnt[];
cnt[^bb] = c0;
cnt[^bb] = c1;
cnt[bb]++;
ans = (ans+cnt[]*mpow(,b)) % Mod;
}
}
printf( "%lld ", ans );
}
};
namespace Task2 {
dnt s[N];
dnt disc[N], dtot;
int bit[][N];
dnt ans;
void init() {
memset( bit, , sizeof(bit) );
}
void modify( int bit[], int a, int delta ) { // a in [1,n]
for( int i=a; i<=dtot; i+=i&-i )
bit[i] += delta;
}
int query( int bit[], int a ) {
int rt = ;
for( int i=a; i; i-=i&-i )
rt += bit[i];
return rt;
}
void main() {
for( int i=; i<=n; i++ )
s[i] = s[i-] + aa[i];
for( int b=; b<=; b++ ) {
dnt cnt = ;
dnt mask = (1LL<<b) - ;
dtot = ;
disc[++dtot] = ;
for( int i=; i<=n; i++ )
disc[++dtot] = s[i] & mask;
sort( disc+, disc++dtot );
dtot = unique( disc+, disc++dtot ) - disc - ;
init();
modify( bit[], lower_bound(disc+,disc++dtot,)-disc, + );
for( int i=; i<=n; i++ ) {
dnt bmid = (s[i]>>b) & ;
dnt brgt = s[i] & mask;
int irgt = lower_bound( disc+, disc++dtot, brgt ) - disc;
if( bmid ) {
cnt += query( bit[], irgt );
cnt += query( bit[], dtot ) - query( bit[], irgt );
} else {
cnt += query( bit[], dtot ) - query( bit[], irgt );
cnt += query( bit[], irgt );
}
modify( bit[bmid], irgt, + );
}
ans |= (cnt&) ? (1LL<<b) : ;
}
printf( "%lld\n", ans );
}
}; int main() {
scanf( "%d", &n );
for( int i=; i<=n; i++ )
scanf( "%d", aa+i );
Task1::main();
Task2::main();
}

最新文章

  1. 再谈C#采集,一个绕过高强度安全验证的采集方案?方案很Low,慎入
  2. 想学好web前端,需要看哪些书籍
  3. java通过LinkedList实现堆栈和队列数据结构
  4. mvc url路由参数的加密和解密
  5. 无线端通用的reset样式
  6. 使用Word 2013向cnblog发布博文
  7. mysql统计一张表中条目个数的方法
  8. 如何覆盖aar的资源
  9. js获取几个月前,几周前时间。
  10. mac上的键盘生活——神级输入法:鼠须管
  11. thinksns消息提示的实现机制(转)
  12. Foursquare 8.0 :聪明人给互联网公司上的流量转化课
  13. Linux学习 -- 服务管理
  14. 友坚恒天.开发板(Cotex-A9 Exynos4412 开发板)
  15. Redis学习笔记--Redis数据过期策略详解
  16. odoo12主题样式模块
  17. Iwconfig/aircrack-ng
  18. 【hbuilder】如何根据Geolocation获得的坐标获取所在城市?
  19. linux shell except tcl login ssh Automatic interaction
  20. Selenium2+python自动化39-关于面试的题

热门文章

  1. IIC串行总线的组成及其工作原理
  2. select()函数用法二
  3. idea中使用tomcat 方式启动spring boot项目
  4. 数据库--mysql介绍
  5. [android]解析XML文件的方法有三种:PULL,DOM,SAM
  6. windows下redis服务操作
  7. Git missing in VS Code – No source control providers
  8. 如何使用django+celery+RabbitMQ实现异步执行
  9. 网络编程--Socket与ServerSocket
  10. Executor