Japan (树状数组)

  • 题目
  • 题意:题意挺好理解的,就是求交叉点。
  • 思路:样例是提示点。按照样例将公路一条一条画一下,就会发现第 i条线的交叉点数就是:在它之前的线段中终点城市标号大于它的数量。需要特殊考虑的是,出发自同一城市的线段,终点需从小到大,才不会互相影响。数据不是按照顺序排好的,所以要对数据按照西海岸城市升序排列,两个城市相同时按东海岸城市升序。
  • #include<cstdio>
    #include<cstring>
    #define lowbit(x) x&(-x)
    #include<algorithm>
    #define LL long long 
    using namespace std;
    const int maxn = 1005,maxl = 1e6+10;
    LL line[maxn];
    struct Line
    {
    	int a,b;
    	bool operator < (const Line &x) const
    	{
    		if(a < x.a) return true;
    		else if(a == x.a && b < x.b) return true;
    		return false;
    	}
    }lines[maxl];
    void update(int x)
    {
    	while(x < maxn)
    	{
    		line[x] ++;
    		x += lowbit(x);
    	}
    } 
    LL query(int x)
    {
    	LL res = 0;
    	while(x > 0)
    	{
    		res += line[x];
    		x -= lowbit(x);
    	}
    	return res;
    }
    int main()
    {
    	int t,n,m,k,cnt = 0;
    	LL ans;
    	scanf("%d",&t);
    	while(t--)
    	{
    		ans = 0;
    		memset(line,0,sizeof(line)); 
    		scanf("%d %d %d",&n,&m,&k);
    		for(int i = 0; i < k; ++ i)
    		{
    			scanf("%d %d",&lines[i].a,&lines[i].b);
    		}
    		sort(lines,lines+k);
    		for(int i = 0; i < k; ++ i)
    		{
    			ans += i - query(lines[i].b);
    			update(lines[i].b);
    		}
    		printf("Test case %d: %lld\n",++cnt,ans);
    	}
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值