傻瓜式做网站/优就业seo
今天都是看的线段树,终于自己能编出简单的来了,虽然还没弄明天离散化,但是先放着,怕文件丢了,先上传再说。
在睡前终于把代码都敲出没有问题出来了,哎哟,累了一天了,继续努力,争取这两天把离散化也学会了!!!
未离散化,也没lazy标记,所以只有在数据比较少的时候才能通过,不然就TLE了。离散化和lazy标记提交通过的代码在下下章!
下面是入门敲的代码,一点一点把线段树的本质搞定。弄明白了线段树是怎么运作的。
#include <iostream>
#include <map>
#include <deque>
#include <vector>
#include <queue>
#include <stack>
#include <string>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <map>
#include <set>
using namespace std;
int INF=1<<30;
const int m=100000; //本来不想离散化了,自己也还没搞定明白离散化,所以相把m开到10^9,但是太大了不行,所以还是学离散化吧
struct node
{int a,b,sum;
}tree[m*5];
void build(int now,int a,int b)
{tree[now].a=a;tree[now].b=b;tree[now].sum=0; //建立完全二叉树,因为每个点可能都要用得到,其实理解最好的方法是看图再理解代码最快if(a==b) return;int mid=(a+b)>>1;build(now*2,a,mid);build(now*2+1,mid+1,b);
}
void update(int i,int a,int b)
{if(tree[i].a==a&&tree[i].b==b){tree[i].sum++;if(tree[i].a==tree[i].b) return;update(i*2,a,(a+b)/2); //找到这条线段之后,这条线段以下的所以儿子都要更新,以使最后的点有,我设这个点为(x,x)即左右端点都相等表示这个点update(i*2+1,(a+b)/2+1,b);return;}int mid=(tree[i].a+tree[i].b)/2;if(a<=mid) update(i*2,a,min(mid,b)); //找到这条线段为此if(b>mid) update(i*2+1,max(a,mid+1),b);
}
int query(int i,int x)
{int mid=(tree[i].a+tree[i].b)>>1;if(tree[i].a==x&&tree[i].b==x) return tree[i].sum; //上面说过,左右端点相等表示这个点if(x<=mid) return query(i*2,x);else return query(i*2+1,x);
}
int main()
{int t,p,k=1,n,m,i,c,d;scanf("%d",&t);while(t--){scanf("%d%d",&n,&m);build(1,1,10000); //建树for(i=0;i<n;i++){scanf("%d%d",&c,&d);update(1,c,d); //更新树}printf("Case #%d:\n",k++);for(i=0;i<m;i++){scanf("%d",&p);printf("%d\n",query(1,p)); //查询}}return 0;
}