POJ3067(树状数组||线段树)

来源:互联网 发布:身份证号的js验证 编辑:程序博客网 时间:2024/05/16 04:45
//东海岸有n个城市 西海岸有m个城市  他们之间有K条路//问这些路共有多少个交点   任意一个交点只有两个路构成//只需要将起点设为东海岸 终点设为西海岸//将路按照起点编号从小到大 终点编号从小到大排序 然后用树状数组或线段树维护即可//树状数组#include <iostream>#include "stdio.h"#include "stdlib.h"#include "string.h"#include "algorithm"#include <queue>using namespace std;struct node {    int op;    int ed;}rd[1000005];int c[1005];int cmp( node a,node b){return a.op==b.op?a.ed<b.ed:a.op<b.op;}int lowbit(int x){    return x&(-x);}void update(int pos,int n){    while(pos<=n)    {        c[pos]++;        pos+=lowbit(pos);    }}int sum(int x){    int ans=0;    while(x>0)    {        ans+=c[x];        x-=lowbit(x);    }    return ans;}int main(){    int t,cnt=0;    scanf("%d",&t);    while(t--)    {        int n,m,k;        long long int ans=0;        scanf("%d%d%d",&n,&m,&k);        for(int i=0;i<k;i++)            scanf("%d%d",&rd[i].op,&rd[i].ed);        sort(rd,rd+k,cmp);        memset(c,0,sizeof c);        for(int i=0;i<k;i++)        {            update(rd[i].ed,m);            ans+=sum(m)-sum(rd[i].ed);        }        printf("Test case %d: %lld\n",++cnt,ans);    }    return 0;}


//线段树

#include <iostream>#include "stdio.h"#include "stdlib.h"#include "string.h"#include "algorithm"#include <queue>using namespace std;struct node {    int op;    int ed;}rd[1000005];struct pnode{    int data;    int left;    int right;}tree[1005<<2];int cmp( node a,node b){return a.op==b.op?a.ed<b.ed:a.op<b.op;}void build(int k,int l,int r){    tree[k].data=0;tree[k].left=l;tree[k].right=r;    if(l == r)  return ;    int mid=(l+r)>>1;    build(k<<1,l,mid);    build(k<<1|1,mid+1,r);}void update(int k,int pos){    int l=tree[k].left,r=tree[k].right;    if(l==r) {        tree[k].data++;        return ;    }    int mid=(l+r)>>1;    if(pos<=mid) update(k<<1,pos);    else update(k<<1|1,pos);    tree[k].data=tree[k<<1].data+tree[k<<1|1].data;}int t_sum(int k,int ll,int rr){    int l=tree[k].left,r=tree[k].right;    if(ll<=l&&rr>=r) return tree[k].data;    int ans=0,mid=(l+r)>>1;    if(ll<=mid) ans+=t_sum(k<<1,ll,rr);    if(rr>mid) ans+=t_sum(k<<1|1,ll,rr);    return ans;}int main(){    int t,cnt=0;    scanf("%d",&t);    while(t--)    {        int n,m,k;        long long int ans=0;        scanf("%d%d%d",&n,&m,&k);        for(int i=0;i<k;i++)            scanf("%d%d",&rd[i].op,&rd[i].ed);        sort(rd,rd+k,cmp);        build(1,1,m);        for(int i=0;i<k;i++)        {            update(1,rd[i].ed);            if(rd[i].ed==m) continue;            ans+=t_sum(1,rd[i].ed+1,m);        }        printf("Test case %d: %lld\n",++cnt,ans);    }    return 0;}


0 0
原创粉丝点击