CodeForces 400E Inna and Binary Logic
来源:互联网 发布:nba数据库统计2017 编辑:程序博客网 时间:2024/05/05 14:55
题意:
n个数字m个操作 n个数组堆成一个金字塔 a[i][j](表示第i行第j个数)=a[i+1][j] & a[i+1][j+1] (反正就是一个三角形… 不懂自己读读题…) 每次操作修改最底层的一个数字 问 整个金字塔的数字的和是多少
思路:
数据很大就算建树也是n-1的高度 所以我放弃这个方向
由于题目中都是位运算 所以自然思路往位上面偏 想到每个元素最大2^17因此可以把17位分开讨论 也就是每一位建一个金字塔
然后发现金字塔里面的一团相邻的1的个数有个特点 就是最底层连续x个1 那么这团1的个数就为x*(x+1)/2
然后就想到一开始先算一个最初形态的ans 然后每次更改元素只需要维护一段连续的1 把ans加加减减就好
用l[i][j]表示在i这个金字塔内最底层第j个数字可以向左延伸l[i][j]个1 同理r[i][j]
那么对该金字塔的一次更改可以分两种情况:
1.将0变成1
那么ans可以先减去更改位置左边和右边的两团1 再加上更改后两边连成一团的1 同时更新l和r数组
2.将1变成0
那么ans可以先减去更改位置所在的那一团1 在加上该位置左边和右边的两团1 同时更新l和r
PS:
我在更新l和r时是暴力的 从纯理论上讲可能会有把我时间卡掉的数据 不过我没想出来 最后AC的结果也是程序只需要202ms 在已经有的解决方案中算快的
代码:
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define M 100010#define K 19int l[K][M],r[K][M],num[M];int n,m;__int64 ans;int main(){ int i,j,k,las,pos,val,from,to; scanf("%d%d",&n,&m); for(i=1;i<=n;i++) scanf("%d",&num[i]); for(i=0;i<K;i++) { las=0; for(j=1;j<=n+1;j++) { if( (1<<i)&num[j] ) { l[i][j]=las; } else { l[i][j]=r[i][j]=j; for(k=las+1;k<j;k++) r[i][k]=j; ans+=(1LL<<i)*(j-las-1)*(j-las)/2; las=j; } } } //printf("%I64d\n",ans); while(m--) { scanf("%d%d",&pos,&val); for(i=0;i<K;i++) { from=((1<<i)&num[pos]); to=((1<<i)&val); if( from == to ) continue; if(from) //1->0 { ans-=(1LL<<i)*(r[i][pos]-l[i][pos]-1)*(r[i][pos]-l[i][pos])/2; l[i][pos]=r[i][pos]=pos; for(j=pos-1;j>=0&&(num[j]&(1<<i));j--) r[i][j]=pos; ans+=(1LL<<i)*(pos-j-1)*(pos-j)/2; for(j=pos+1;j<=n+1&&(num[j]&(1<<i));j++) l[i][j]=pos; ans+=(1LL<<i)*(j-pos-1)*(j-pos)/2; } else //0->1 { ans-=(1LL<<i)*(r[i][pos-1]-l[i][pos-1]-1)*(r[i][pos-1]-l[i][pos-1])/2; ans-=(1LL<<i)*(r[i][pos+1]-l[i][pos+1]-1)*(r[i][pos+1]-l[i][pos+1])/2; ans+=(1LL<<i)*(r[i][pos+1]-l[i][pos-1]-1)*(r[i][pos+1]-l[i][pos-1])/2; l[i][pos]=l[i][pos-1]; r[i][pos]=r[i][pos+1]; for(j=pos-1;j>=0&&(num[j]&(1<<i));j--) r[i][j]=r[i][pos]; for(j=pos+1;j<=n+1&&(num[j]&(1<<i));j++) l[i][j]=l[i][pos]; } } num[pos]=val; printf("%I64d\n",ans); } return 0;}
0 0
- CodeForces 400E Inna and Binary Logic
- Codeforces 400E Inna and Binary Logic(位运算+暴力)
- !codeforces 400E Inna and Binary Logic-yy-(位运算)
- Inna and Binary Logic
- CF 400E Inna and Binary Logic(多维线段树)
- Codeforces 390 E. Inna and Large Sweet Matrix
- CodeForces 390E Inna and Large Sweet Matrix
- codeforces 400A - Inna and Choose Options
- Codeforces 400A Inna and Choose Options
- CodeForces 400A Inna and Choose Options
- Codeforces 400A Inna and Choose Options
- CodeForces 400A Inna and Choose Options
- CodeForces 400A Inna and Choose Options
- Codeforces 400 A. Inna and Choose Options
- codeforces Inna and Choose Options
- codeforces Inna and Alarm Clock
- codeforces Inna, Dima and Song
- Codeforces 390E Inna and Large Sweet Matrix(树状数组)
- 九度oj 题目1005:Graduate Admission 【ZJU2011考研机试题4】
- The Pilots Brothers' refrigerator
- ASP.NET动态绘制汉字、字母和数字验证码
- 大数据时代---维克托•迈尔•舍恩伯格
- Problem accessing /nn_browsedfscontent.jsp
- CodeForces 400E Inna and Binary Logic
- POJ - 3126 Prime Path(BFS, 素数筛法)
- vc++下出现的问题
- 修电路板之经验
- HDU 1503 最长公共子序列的变形(重点在输出)
- prim学习
- libevent源码分析--I/O 定时 信号 被处理的安排
- 复制与粘贴
- PHP截取汉字乱码问题