这题整整debug了两个小时
不同组居然要初始化 本以为built函数里面已经初始化好了!!!!!
其他无需注意
#include<cstdio> #include<cstring> using namespace std; int n,p,a,b,m,x,y,ans; struct node { int l,r,w,f; }tree[400001]; inline void build(int k,int ll,int rr)//建树 { tree[k].l=ll,tree[k].r=rr; if(tree[k].l==tree[k].r) { tree[k].w=0; return; } int m=(ll+rr)/2; build(k*2,ll,m); build(k*2+1,m+1,rr); tree[k].w=tree[k*2].w+tree[k*2+1].w; } inline void down(int k)//标记下传 { tree[k*2].f+=tree[k].f; tree[k*2+1].f+=tree[k].f; tree[k*2].w+=tree[k].f*(tree[k*2].r-tree[k*2].l+1); tree[k*2+1].w+=tree[k].f*(tree[k*2+1].r-tree[k*2+1].l+1); tree[k].f=0; } inline void ask_point(int k)//单点查询 { if(tree[k].l==tree[k].r) { ans=tree[k].w; return ; } if(tree[k].f) down(k); int m=(tree[k].l+tree[k].r)/2; if(x<=m) ask_point(k*2); else ask_point(k*2+1); } inline void change_interval(int k)//区间修改 { if(tree[k].l>=a&&tree[k].r<=b) { tree[k].w+=(tree[k].r-tree[k].l+1)*y; tree[k].f+=y; return; } if(tree[k].f) down(k); int m=(tree[k].l+tree[k].r)/2; if(a<=m) change_interval(k*2); if(b>m) change_interval(k*2+1); tree[k].w=tree[k*2].w+tree[k*2+1].w; } int main() { while(scanf("%d",&n)==1&&n) { memset(tree,0,sizeof(tree)); build(1,1,n); y=1; for(int i=1;i<=n;i++) { scanf("%d%d",&a,&b); change_interval(1); } for(x=1;x<n;x++) { ans=0; ask_point(1); printf("%d ",ans); } ans=0; ask_point(1); printf("%d ",ans); } return 0; }
可以用树状数组来做
普通的树状数组是改单点 求区间 或者改单点 求单点(做差)
但是树状数组也可以改区间 求单点 sum即为单点
每次更新为 参数~n 均+=val
#include <cstdio> #include <cstring> const int maxn = 100005; int c[maxn],n; int Lowbit(int x) { return x&(-x); } void update(int k,int x) { while(k <= n) { c[k] += x; k += Lowbit(k); } } int getsum(int x) { int sum = 0; while(x > 0) { sum += c[x]; x -= Lowbit(x); } return sum; } int main() { int a,b; while(scanf("%d",&n)&&n!=0) { memset(c,0,sizeof(c)); for(int i=0; i<n; i++) { scanf("%d%d",&a,&b); update(a,1); update(b+1,-1); } for(int i=1; i<n; i++) printf("%d ",getsum(i)); printf("%d ",getsum(n)); } return 0; }