hdu 1166 敌兵布阵 + Dairy
来源:互联网 发布:淘宝店铺链接转换微信 编辑:程序博客网 时间:2024/06/04 17:50
Today is 4.30,the second day in 2S.
遇见了一个十分humorous的把妹老师。嗯南方人。所化四泽阳的。
说正事:
今天第一题,两种解,打算好好写写,但是据说我写的东西跟八级阅读题一样。。【【【黑线
第一种方法:
树状数组。
其神奇所在,大概是lowbit数组。
由图可知,c1=a1,c2=a1+a2,c3=a3,c4=a1+a2+a3+a4……
一次类推可知,i是奇数时,ai=ci;i是偶数是(c6=a5+a6),要看i里含2
的几次幂的因数。比如c4里是2的2次幂,所以是a1+a2+a3+a4;c6只含2,所以是a5+a6; 所以我们有有公式:cn=a(n-2^k+1)+………+an(其中 k 为 n 的二进制表示中从右往左数的 0 的个数)。 eg:6的二进制是110,那就是6-2^1+1,所以就是a5+a6。
2^k怎么求呢?
int lowbit(int x){ return x&(-x);}
如上,其实是x&(~(x-1))…..
举个例子:
6 110
~(5) 010
6&~(5) 010 ==2 !
剩下的简单的多了,一个是插入操作,还有一个修改。
看代码好了
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;#define N 50005int n;int a[N],c[N];int lowbit(int x){ return x&(-x);}void add(int i,int w){ while(i<=n){ c[i]+=w; i=i+lowbit(i); //增加是要往后跳的!! }}int sum(int i){ int sum=0; while(i>0){ sum+=c[i]; i=i-lowbit(i); //求和则是往前。 } return sum;}int main() { int t,i,tmp,x,y,cases=1; char op[100]; scanf("%d",&t); while(t--) { printf("Case %d:\n",cases++); memset(a,0,sizeof(a)); memset(c,0,sizeof(c)); //记得要清空数组!! scanf("%d",&n); for(i=1;i<=n;i++) { scanf("%d",&tmp); add(i,tmp); } while(scanf("%s",op)&& op[0]!='E') { scanf("%d%d",&x,&y); if(op[0]=='A') add(x,y); else if(op[0]=='S') add(x,-y); else printf("%d\n",sum(y)-sum(x-1)); } } return 0; } /*1101 2 3 4 5 6 7 8 9 10Query 1 3Add 3 6Query 2 7Sub 10 2Add 6 3Query 3 10End */
第二种方法:
–
线段树:
没什么解释的?
直接看好了
#include<cstdio>#include<algorithm>#include<cstring>#include<iostream>using namespace std;struct Line{ int left,right; int val;}line[200001];int n,ans,jy,cases=1;int c[200001];char op[11];void build(int l,int r,int num){ if(l == r) { scanf("%d",&line[num].val); return; } line[num].left=l; line[num].right=r; int mid=(l+r)/2; build(l,mid,2*num); build(mid+1,r,2*num+1); line[num].val=line[num*2].val+line[num*2+1].val;//更新父亲节点 }void modify(int a,int b,int s,int t,int num){ if(s == t){ line[num].val+=b; return; } int mid=(s+t)/2; if(a<=mid) modify(a,b,s,mid,num*2); else modify(a,b,mid+1,t,num*2+1); line[num].val=line[num*2].val+line[num*2+1].val;}int query(int a,int b,int s,int t,int num){// printf("%d %d %d\n",a,b,num); if(a<=s && b>=t){ return line[num].val; //printf("lal %d\n",line[num].val);} int mid=(s+t)/2; int res=0; if(a<=mid) res+=query(a,b,s,mid,num*2); //printf("%d\n",res); if(b>mid) res+=query(a,b,mid+1,t,num*2+1); //printf("%d\n",res); return res; }int main(){ int T; scanf("%d",&T); while(T--){ printf("Case %d:\n",cases++); scanf("%d",&n); build(1,n,1); /* for(int i=1;i<=10;i++){ printf("%d \n",line[i].val); }*/ int x,y; //while(scanf("%s",op) && op[0]!='E'){ while(1){ scanf("%s",op); if(op[0] == 'E') break; //scanf("%d%d",&x,&y); if(op[0] == 'A') { scanf("%d%d",&x,&y); modify(x,y,1,n,1); } if(op[0] == 'S') { scanf("%d%d",&x,&y); modify(x,-y,1,n,1); } if(op[0] == 'Q'){ scanf("%d%d",&x,&y); printf("%d\n",query(x,y,1,n,1)); } } }}
啦啦啦,拖到现在才写完,马上就要上课了。
0 0
- hdu 1166 敌兵布阵 + Dairy
- HDU 1166 敌兵布阵
- HDU 1166 敌兵布阵
- hdu 1166 敌兵布阵
- hdu 1166 敌兵布阵
- HDU 1166 敌兵布阵
- hdu 1166 敌兵布阵
- hdu 1166 敌兵布阵
- hdu 1166敌兵布阵
- hdu 1166 敌兵布阵
- hdu 1166 敌兵布阵
- HDU 1166 敌兵布阵
- hdu 1166 敌兵布阵
- hdu 1166 敌兵布阵
- HDU 1166 敌兵布阵
- HDU 1166 - 敌兵布阵
- hdu 1166 敌兵布阵
- hdu 1166 敌兵布阵
- Title three:may day
- 【笔记】MakeFile怎么写
- 【Linux】-----简单易学的安装
- Qt实现窗口间数据交换
- 二叉树梳理
- hdu 1166 敌兵布阵 + Dairy
- 自定义控件三部曲之绘图篇(十二)——Paint之setXfermode(三)
- 读书笔记_暗时间
- 错误:Please ensure that adb is correctly located at 'D:\Android\new\android-sdk-windows\android-sdk-wi
- Android学习之界面篇(六)ViewPager学习与Android引导界面的实现
- Title Four:Rainy
- 5-7 六度空间 (30分)
- mvc小结
- HDU 5675 ztr loves math——BestCoder Round #82(div.2)