[Luo Gu P2154] SDOI2009 pious owner of the tomb

Problem Description

Small W is a new creation of the cemetery manager. Cemetery can be seen as a rectangle of N × M, each rectangular grid, or a species of evergreen with either a home yet cemetery.

Local residents are very devout Christians, they are willing to advance to find a suitable cemetery for themselves. In order to realize their good faith in the Lord, they want their cemetery has a higher loyalty.

A loyalty cemetery is the number to the graveyard as the center of the cross. A cross can be seen as the middle of the cemetery, the cemetery positive, positive, the positive Left side, front and right have exactly k evergreen trees.

Small W would like to know the total loyalty he managed all this cemetery cemetery is.

Input Format

The first line of the input file religious.in contains two space-separated positive integers N and M, represents a cemetery width and length, so the total of the rectangular cemetery (N + 1) × (M + 1) lattice points, the lower left coordinate angle is (0, 0), the coordinates of the upper right corner is (N, M).

The second line contains a positive integer W, represents the number of cemetery evergreen.

From the third row were W rows, each row comprising two spaces separated by a non-negative integer xi and yi, a graph of an evergreen tree. Enter evergreens ensure that no two have the same coordinates.

The last line contains a positive integer k, the title meaning as shown.

Output Format

Religious.out output file contains only a non-negative integer, represents the sum of this loyalty all cemetery cemetery. For convenience, the answer to the modulo 2,147,483,648.

Sample input

5 6
13
0 2
0 3
1 2
1 3
2 0
2 1
2 4
2 5
2 6
3 2
3 3
4 3
5 2
2

Sample Output

6

Explanation

Figure, cemetery (2, 2), and (2, 3) cross each center 3, i.e., they are 3 loyalty. Other tomb

Loyalty to zero.

img

For 30% of the data satisfies 1 ≤ N, M ≤ 1,000.

For 60% of the data satisfies 1 ≤ N, M ≤ 1,000,000.

To 100% of the data satisfies 1 ≤ N, M ≤ 1,000,000,000,0 ≤ xi ≤ N, 0 ≤ yi ≤ M, 1 ≤ W ≤ 100,000,1 ≤ k ≤ 10.

50% of the data is present, satisfying 1 ≤ k ≤ 2.

25% of the data exists, satisfying 1 ≤ W ≤ 10000.

Resolve

A set point above has a tree, the tree below b, c there are trees on the left, right is d tree. Then, for the loyalty point A
\ [C_a ^ k * C_b ^
k * C_c ^ k * C_d ^ k \] between the same two trees ordinate, the number of right and left unchanged in all the cemeteries, these cemetery the loyalty number is the product of the combination and the right and left of the product multiplied by the number of combinations of each column. We have the following practices: every tree in ascending order according to the vertical axis, vertical axis according to the same abscissa from small to large. Maintaining the product of the number of combinations on each array column with a tree, i.e. \ (C_a C - b ^ + K ^ K \) . Each scan line, the statistical answer between two adjacent trees, can be realized with a range of summation. Update the value of the tree array after each scan line.

Code

#include <iostream>
#include <cstdio>
#include <algorithm>
#define int long long
#define N 2000002
using namespace std;
const int mod=2147483648;
struct node{
    int x,y;
}a[N];
int n,m,w,t,i,j,k,vx[N],vy[N],c[N],sum[N],num[N],f[N][12],n1,n2;
int read()
{
    char c=getchar();
    int w=0;
    while(c<'0'||c>'9') c=getchar();
    while(c<='9'&&c>='0'){
        w=w*10+c-'0';
        c=getchar();
    }
    return w;
}
int my_comp(const node &a,const node &b)
{
    if(a.y==b.y) return a.x<b.x;
    return a.y<b.y;
}
int lowbit(int x)
{
    return x&(-x);
}
void add(int x,int y)
{
    for(int i=x;i<=n1;i+=lowbit(i)) c[i]=(c[i]+y+mod)%mod;
}
int ask(int x)
{
    int ans=0;
    for(int i=x;i>=1;i-=lowbit(i)) ans=(ans+c[i]+mod)%mod;
    return ans;
}
signed main()
{
    n=read();m=read();w=read();
    for(i=1;i<=w;i++){
        a[i].x=read(),a[i].y=read();
        vx[i]=a[i].x;
        vy[i]=a[i].y;
    }
    t=read();
    f[0][0]=1;
    for(i=1;i<=w;i++){
        f[i][0]=1;
        for(j=1;j<=t;j++) f[i][j]=(f[i-1][j]+f[i-1][j-1])%mod;
    }
    sort(vx+1,vx+w+1);
    sort(vy+1,vy+w+1);
    sort(a+1,a+w+1,my_comp);
    n1=unique(vx+1,vx+w+1)-vx-1;
    n2=unique(vy+1,vy+w+1)-vy-1;
    for(i=1;i<=w;i++){
        a[i].x=lower_bound(vx+1,vx+n1+1,a[i].x)-vx;
        a[i].y=lower_bound(vy+1,vy+n2+1,a[i].y)-vy;
        sum[a[i].x]++;
    }
    i=j=1;
    int ans=0;
    while(i<=w){
        while(a[i].y==a[j].y) j++;
        int cnt=j-i,now=1;
        for(k=i+1;k<j;k++,now++){
            int l=a[k-1].x,r=a[k].x;
            ans=(ans+(ask(r-1)-ask(l)+mod)%mod*f[now][t]%mod*f[cnt-now][t]%mod)%mod;
        }
        for(k=i;k<j;k++){
            int p=a[k].x;
            add(p,-f[num[p]][t]*f[sum[p]-num[p]][t]%mod);
            num[p]++;
            add(p,f[num[p]][t]*f[sum[p]-num[p]][t]%mod);
        }
        i=j;
    }
    printf("%lld\n",(ans%mod+mod)%mod);
    return 0;
}

Guess you like

Origin www.cnblogs.com/LSlzf/p/11704336.html