3 2 1
先附上自己的代码,虽然是超时,但毕竟是自己写的,现在的水平还是很low,不知道再怎么优化,不过后面有两种超赞的解法
#include<stdio.h> #include<string.h> #include <string> #include <queue> #include <iostream> using namespace std; typedef struct node{ int l,r,value; }temp; int n; temp node[100000]; void init(int left,int right,int rt) { node[rt].l=left; node[rt].r=right; node[rt].value=0; if (left==right) return; int mid=(left+right)>>1; init(left,mid,rt<<1); init(mid+1,right,rt<<1|1); } void update(int rt,int l,int r) { if (node[rt].l==node[rt].r) { node[rt].value++; //这些点都是父节点,到最后要输出子节点 return; } int mid=(node[rt].l+node[rt].r)>>1; if (r<=mid) update(rt<<1,l,r); else if (l>mid) update(rt<<1|1,l,r); else { update(rt<<1,l,mid); update(rt<<1|1,mid+1,r); } } void out(int rt,int sum) { if (node[rt].l==node[rt].r) { printf("%d",sum+node[rt].value); if (node[rt].l!=n) printf(" "); return ; } out(rt<<1,sum+node[rt].value); out(rt<<1|1,sum+node[rt].value); } int main() { while (~scanf("%d",&n),n) { int i; init(1,n,1); int a,b; for (i=1;i<=n;i++) { scanf("%d%d",&a,&b); update(1,a,b); } out(1,0); printf("\n"); } return 0; }
看人家写的代码,真是一种享受,惊叹,感觉自己弱爆了,关于位运算还是没大了解
#include <stdio.h> #include <string.h> const int MAXN=110000; int n,c[MAXN]; int lowbit(int x) //计算2^k { x=x&-x; return x; } void update(int num,int val) //向下查询,num是要更新的子节点,val是要修改的值 { while(num>0) { c[num]+=val; num-=lowbit(num); } } int getSum(int num) //向上统计每个区间被染色的次数 { int sum=0; while(num<=n) { sum+=c[num]; num+=lowbit(num); } return sum; } int main() { int a,b; while(scanf("%d",&n),n) { memset(c,0,sizeof(c)); for(int i=0;i<n;i++) { scanf("%d%d",&a,&b); //将b以下区间+1 update(b,1); //将a以下区间-1 update(a-1,-1); } for(int j=1;j<n;j++) { printf("%d ",getSum(j)); } printf("%d\n",getSum(n)); } return 0; }
#include<iostream> using namespace std; struct node { int left,right; int sum,lnc; }tree[300000]; int num[100000]; void init(int id,int l,int r) { if(l==r) { tree[id].sum=num[l]; tree[id].left=tree[id].right=l; tree[id].lnc=0; return ; } init(id*2,l,(l+r)/2); init(id*2+1,(l+r)/2+1,r); tree[id].sum=tree[2*id].sum+tree[id*2+1].sum; tree[id].lnc=0; tree[id].left=l; tree[id].right=r; } void update(int id,int l,int r,int val) { if(tree[id].left==l&&tree[id].right==r) { tree[id].lnc+=val; return ; } tree[id].sum+=val*(r-l+1); int mid=(tree[id].left+tree[id].right)/2; if(r<=mid) update(2*id,l,r,val); else if(l>=mid+1) update(2*id+1,l,r,val); else { update(2*id,l,mid,val); update(2*id+1,mid+1,r,val); } } int read(int id,int l,int r) { if(tree[id].left==l&&tree[id].right==r) { return tree[id].sum+tree[id].lnc*(r-l+1); } tree[id].sum+=tree[id].lnc*(tree[id].right-tree[id].left+1); int val=tree[id].lnc; int mid=(tree[id].left+tree[id].right)/2; update(2*id,tree[id].left,mid,val); update(2*id+1,mid+1,tree[id].right,val); tree[id].lnc=0; if(r<=mid) return read(2*id,l,r); else if(l>=mid+1) return read(2*id+1,l,r); else { return read(2*id,l,mid)+read(2*id+1,mid+1,r); } } int main() { int n,i,a,b,temp; while(scanf("%d",&n)&&n) { memset(num,0,sizeof(num)); memset(tree,0,sizeof(tree)); init(1,1,n); temp=n; while(temp--) { scanf("%d%d",&a,&b); update(1,a,b,1); } for(i=1;i<=n;i++) { printf("%d",read(1,i,i)); if(i!=n) printf(" "); else printf("/n"); } } return 0; }