1. 程式人生 > >ZOJ - 4082:Little Sub and his Geometry Problem (雙指針)

ZOJ - 4082:Little Sub and his Geometry Problem (雙指針)

span it is pre plan sep std lov next def

Little Sub loves math very much, and has just come up with an interesting problem when he is working on his geometry homework.

It is very kind of him to share this problem with you. Please solve it with your coding and math skills. Little Sub says that even Mr.Potato can solve it easily, which means it won‘t be a big deal for you.

The problem goes as follows:

Given two integers and , and points with their Euclidean coordinates on a 2-dimensional plane. Different points may share the same coordinate.

Define the function

where

You are required to solve several queries.

In each query, one parameter is given and you are required to calculate the number of integer pairs such that and .


Input

There are multiple test cases. The first line of the input contains an integer (), indicating the number of test cases. For each test case:

The first line contains two positive integers and ().

For the following lines, the -th line contains two integers and (), indicating the coordinate of the -th point.

The next line contains an integer (), indicating the number of queries.

The following line contains integers (), indicating the parameters for each query.

It‘s guaranteed that at most 20 test cases has .

Output

For each test case, output the answers of queries respectively in one line separated by a space.

Please, DO NOT output extra spaces at the end of each line, or your answer may be considered incorrect!

Sample Input
2
4 2
1 1
2 3
5
1 2 3 4 5
15 5
1 1 
7 3 
5 10 
8 6 
7 15
3
25 12 31
Sample Output
2 3 4 1 2
5 11 5

題意:給定二維N*N平面,以及M個點,Q次詢問,每次詢問給出C,問平面上有多少個點滿足:左下方的點到它的距離和為C。

思路:發現符合條件的點在每個X線上最多一個一個點滿足,而且這些點具有單調性,即X遞增,Y遞減。假設當前點(i,j),左下方的點個數為tot,

那麽距離和=(i+j)*tot-sum; 我們維護一些軸上的學習,然後雙指針去搞就好了。

#include<bits/stdc++.h>
#define ll long long
#define rep(i,w,v) for(int i=w;i<=v;i++)
using namespace std;
const int maxn=200010;
struct in{
    int x,y;
    bool friend operator<(in w,in v){
        if(w.x==v.x) return w.y<v.y; return w.x<v.x;
    }
}s[maxn];
int num[maxn],tot,ans; ll sum,C,d[maxn];
int main()
{
    int T,N,M,Q;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&N,&M);
        rep(i,1,M) {
            scanf("%d%d",&s[i].x,&s[i].y);
        }
        sort(s+1,s+M+1);  scanf("%d",&Q);
        rep(kk,1,Q){
           scanf("%lld",&C);
           int p=0,q=N; rep(i,1,N) num[i]=0,d[i]=0;
           ans=tot=0; sum=0;
           rep(i,1,N){
              while(p+1<=M&&s[p+1].x<=i) {
                 p++; if(s[p].y<=q){
                    tot++; num[s[p].y]++;
                    sum+=s[p].x+s[p].y;
                    d[s[p].y]+=i;
                 }
              }
              while((ll)tot*(i+q)-sum>C){
                 tot-=num[q];
                 sum-=(d[q]+(ll)num[q]*q);
                 q--;
              }
              if((ll)tot*(i+q)-sum==C) ans++;
           }
           if(kk!=1) putchar( );
           printf("%d",ans);
        }
        puts("");
    }
    return 0;
}

ZOJ - 4082:Little Sub and his Geometry Problem (雙指針)