【线段树】【4-6组队赛】Problem H

来源:互联网 发布:湖南省地质测绘院 知乎 编辑:程序博客网 时间:2024/06/10 00:11

Problem Description

#include <iostream>
#include <algorithm>
using namespace std;

int n,a[110000],b[110000],c[110000],d[110000];
int main()
{
      while(cin>>n)
      {
            for(int i=0;i<n;++i)  cin>>a[i];
            for(int i=0;i<n;++i)  cin>>b[i];
            for(int i=0;i<n;++i)  cin>>c[i];
            for(int i=0;i<n;++i)  cin>>d[i];

            for(int i=0;i<n;++i)
                  if(a[i]>b[i])  swap(a[i],b[i]);
            for(int i=0;i<n;++i)
                  if(c[i]>d[i])  swap(c[i],d[i]);

            for(int i=0;i<n;++i)
            {
                  int ans=0;
                  for(int j=0;j<n;++j)
                        if(a[i]<=c[j]&&d[j]<=b[i])  ans++;
                  cout<<ans<<endl;
            }
      }
      return 0;
}


Even you are brave enough still, I really not recommend you to copy the code and just submit it.

Input

Input contains several cases.
Each case begins with an integer n (0<n<=100000).
Then follow with 4 lines representing a[ ],b[ ],c[ ] and d[ ], all values are located in [1,100000].

Output

For each case, just write out the answer as what the code do.

Sample Input

41 1 1 21 1 1 21 1 1 11 1 1 1

Sample Output

4440


题目大意:

给你二组线段A,B 询问A组中每一个线段包含了多少B组线段


将A,B按左端点排序;

那么当B前面线段若不满足当前A了 ,就可以废弃不用了,即B.x<A[now].x。


所以未被删除的B线段都是满足了左端点,现在只需要求是否满足右端点即可。

用线段树来维护B的右端点。若B一条废弃不用,更新线段树即可。每次查询【0-A[now].y】有多少元素即可


nlogn的复杂度。


最后还要按序号排序回来,因为要按输入顺序输出,代码如下:


#include <cstdio>#include <cstdlib>#include <cmath>#include <cstring>#include <ctime>#include <algorithm>#include <iostream>#include <sstream>#include <string>#define oo 0x13131313#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1using namespace std;const int maxn=100000+5;struct node{    int x,y,num,ans;}A[maxn],B[maxn];int n;int tree[maxn<<2];bool cmp(node a,node b){    return a.x<b.x;}bool cmp1(node a,node b){    return a.num<b.num;}void pushup(int rt){    tree[rt]=tree[rt<<1]+tree[rt<<1|1];}int build(int l,int r,int rt){    if(l==r) {tree[rt]=0;return 0;}    int m=(l+r)>>1;    build(lson);    build(rson);    pushup(rt);}int updata(int p,int k,int l,int r,int rt)//单点更新{    int m;    if(l==r) {tree[rt]+=k;return 0;}    m=(l+r)>>1;    if(p<=m) updata(p,k,lson);    else updata(p,k,rson);    pushup(rt);}int query(int L,int R,int l,int r,int rt){    int temp=0,m;    if(L<=l&&r<=R) return tree[rt];    m=(l+r)>>1;    if(L<=m) temp=temp+query(L,R,lson);    if(R>m)  temp=temp+query(L,R,rson);    return temp;}void input(){            for(int i=0;i<n;++i)  {scanf("%d",&A[i].x);A[i].num=i;}            for(int i=0;i<n;++i)  scanf("%d",&A[i].y);            for(int i=0;i<n;++i)  scanf("%d",&B[i].x);            for(int i=0;i<n;++i)  scanf("%d",&B[i].y);                for(int i=0;i<n;++i)                  if(A[i].x>A[i].y)  swap(A[i].x,A[i].y);                for(int i=0;i<n;++i)                  if(B[i].x>B[i].y)  swap(B[i].x,B[i].y);            sort(B,B+n,cmp);            sort(A,A+n,cmp);}void solve(){     int tot=0;     for(int i=0;i<n;i++)     {        updata(B[i].y,1,1,maxn-1,1);     }     for(int i=0;i<n;i++)     {        int ans=0;        while(B[tot].x<A[i].x&&tot<n) {                                    updata(B[tot].y,-1,1,maxn-1,1);                                    tot++;                               }        ans=query(1,A[i].y,1,maxn-1,1);        A[i].ans=ans;     }     sort(A,A+n,cmp1);     for(int i=0;i<n;i++) printf("%d\n",A[i].ans);}void init(){    freopen("a.in","r",stdin);    freopen("a.out","w",stdout);}int main(){   //  init();while(scanf("%d",&n)!=EOF)    {        input();        build(1,maxn-1,1);        solve();    }}





0 0
原创粉丝点击