답안 #54577

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
54577 2018-07-04T06:49:18 Z 노영훈(#1490) Pairs (IOI07_pairs) C++11
100 / 100
3199 ms 511768 KB
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int MX=100010, inf=2e9;

int b,n,d,m;

ll ans=0;

inline int _min(int x, int y) { return x<y ? x : y; }

void solve1(){
    int A[MX];
    for(int i=1; i<=n; i++) cin>>A[i];
    sort(A+1, A+n+1);
    for(int i=1, r=1; i<=n; i++){
        while(r<n && A[r+1]<=A[i]+d) r++;
        ans+=r-i;
    }
}

struct _SEG {
    int tree[150000*4], n;
    void init(int sz){
        n=sz;
        for(int i=1; i<150000*4; i++) tree[i]=0;
    }
    void upt(int v, int s, int e, int pos, int val){
        if(pos<s || e<pos) return;
        tree[v]+=val;
        if(s==e) return;
        upt(v*2,s,(s+e)/2,pos,val);
        upt(v*2+1,(s+e)/2+1,e,pos,val);
    }
    int sum(int v, int s, int e, int l, int r){
        if(e<l || r<s) return 0;
        if(l<=s && e<=r) return tree[v];
        return sum(v*2,s,(s+e)/2,l,r) + sum(v*2+1,(s+e)/2+1,e,l,r);
    }
    void upt(int pos, int val){
        upt(1,1,n,pos,val);
    }
    int sum(int l, int r){
        l=max(l,1);
        r=_min(r,n);
        if(r<l) return 0;
        return sum(1,1,n,l,r);
    }
};
struct pt2 {
    int x, y;
    bool operator < (const pt2 &p) const {
        return x-y<p.x-p.y;
    }
    void scan(){
        cin>>x>>y;
    }
};
void solve2(){
    _SEG Seg; Seg.init(150000);
    pt2 P[MX];
    for(int i=1; i<=n; i++) P[i].scan();
    sort(P+1, P+n+1);
    for(int i=1, r=0, l=1; i<=n; i++){
        while(r<n && P[r+1].x-P[r+1].y<=P[i].x-P[i].y+d){
            r++;
            Seg.upt(P[r].x+P[r].y,1);
        }
        while(l<=i){
            Seg.upt(P[l].x+P[l].y,-1);
            l++;
        }
        ans+=Seg.sum(P[i].x+P[i].y-d, P[i].x+P[i].y+d);
    }
}

struct pt3 {
    int x, y, z;
    void scan(){
        cin>>x>>y>>z;
    }
};

int A[76][76][76][76]; // '/'
int B[76][76][76][76]; // '\'
int C[151][76][76][76];// 마름모

inline int geta(int k, int x, int y, int z){
    if(x<1 || y<1 || z<1 || m<x || m<y || m<z || k<1) return 0;
    return A[k][x][y][z];
}
inline int getb(int k, int x, int y, int z){
    if(x<1 || y<1 || z<1 || m<x || m<y || m<z || k<1) return 0;
    return B[k][x][y][z];
}
inline int getc(int k, int x, int y, int z){
    if(x<1 || y<1 || z<1 || m<x || m<y || m<z || k<1) return 0;
    k=_min(k, 150);
    return C[k][x][y][z];
}

void solve3(){
    pt3 P[MX];
    for(int i=1; i<=n; i++) P[i].scan();
    if(d>=3*m){
        ans=1LL*n*(n-1)/2;
        return;
    }

    for(int i=1; i<=n; i++){
        int x=P[i].x, y=P[i].y, z=P[i].z;
        A[1][x][y][z]++;
        B[1][x][y][z]++;
        C[1][x][y][z]++;
    }

    for(int i=2; i<=75; i++){
        for(int x=1; x<=m; x++)
            for(int y=1; y<=m; y++)
                for(int z=1; z<=m; z++){
                    A[i][x][y][z]=geta(i-1, x, y-1, z-1)+A[1][x][y][z];
                    B[i][x][y][z]=getb(i-1, x, y+1, z-1)+B[1][x][y][z];
                }
    }

    for(int i=2; i<=150; i++){
        for(int x=1; x<=m; x++)
            for(int y=1; y<=m; y++)
                for(int z=1; z<=m; z++){
                    int &now=C[i][x][y][z]; now=0;
                    // bool deb=false;
                    // if(i==3 && x==1 && y==2 && z==1) deb=true;
                    now+=getc(i-1,x,y,z);
                    {
                        int k=_min(z+i-1, m);
                        int l=z+i-1-k;
                        if(i-1-l>=1 && y-l>=1) now+=A[i-1-l][x][y-l][k];
                        // now+=geta(i-1-l,x,y-l,k);
                        // if(deb) cout<<i-1-l<<" : "<<geta(i-1-l,x,y-l,k)<<'\n';
                    }
                    {
                        int k=max(1,y-i+1);
                        int l=k-(y-i+1);
                        if(i-1-l>=1 && z-l>=1) now+=B[i-1-l][x][k][z-l];
                        // now+=getb(i-1-l,x,k,z-l);
                        // if(deb) cout<<i-1-l<<' '<<k<<' '<<z+l<<" : "<<getb(i-1-l,x,k,z+l)<<'\n';
                    }
                    {
                        int k=_min(y+i-1, m);
                        int l=y+i-1-k;
                        if(i-l>=1 && z-l>=1) now+=A[i-l][x][k][z-l];
                        // now+=geta(i-l,x,k,z-l);
                        // if(deb) cout<<i-l<<" : "<<geta(i-l,x,k,z-l)<<'\n';
                    }
                    {
                        int k=_min(z+i-2, m);
                        int l=z+i-2-k;
                        if(i-2-l>=1 && y+1+l<=m && k>=1) now+=B[i-2-l][x][y+1+l][k];
                        // now+=getb(i-2-l,x,y+1+l,k);
                        // if(deb) cout<<i-2-l<<" : "<<getb(i-2-l,x,y+1+l,k)<<'\n';
                    }
                    // if(deb) cout<<'\n';
                }
    }

/*
    for(int i=1; i<=5; i++, cout<<'\n')
        for(int x=1; x<=m; x++, cout<<'\n')
            for(int y=1; y<=m; y++, cout<<'\n')
                for(int z=1; z<=m; z++){
                    cout<<getc(i,x,y,z);
                }

    cout<<"A:\n";
    for(int i=1; i<=5; i++, cout<<'\n')
        for(int x=1; x<=m; x++, cout<<'\n')
            for(int y=1; y<=m; y++, cout<<'\n')
                for(int z=1; z<=m; z++){
                    cout<<geta(i,x,y,z);
                }
*/
    for(int i=1; i<=n; i++){
        int x=P[i].x, y=P[i].y, z=P[i].z;
        ll now=0;
        for(int a=1; a<=m; a++){
            now+=getc(d-abs(a-x)+1,a,y,z);
            // cout<<getc(d-abs(a-x)+1,a,y,z)<<' ';
        }
        // cout<<'\n'<<now<<'\n';
        ans+=now-1;
    }
    ans/=2;
}

int main(){
    ios::sync_with_stdio(0); cin.tie(0);
    cin>>b>>n>>d>>m;
    if(b==1) solve1();
    if(b==2) solve2();
    if(b==3) solve3();
    cout<<ans;
    return 0;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 376 KB Output is correct
2 Correct 2 ms 376 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 564 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 19 ms 824 KB Output is correct
2 Correct 16 ms 884 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 25 ms 884 KB Output is correct
2 Correct 22 ms 912 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 24 ms 952 KB Output is correct
2 Correct 24 ms 952 KB Output is correct
3 Correct 25 ms 952 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 6 ms 2916 KB Output is correct
2 Correct 5 ms 3044 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 62 ms 3748 KB Output is correct
2 Correct 60 ms 3748 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 79 ms 3756 KB Output is correct
2 Correct 79 ms 3756 KB Output is correct
3 Correct 74 ms 3756 KB Output is correct
4 Correct 75 ms 3756 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 116 ms 3860 KB Output is correct
2 Correct 109 ms 3860 KB Output is correct
3 Correct 84 ms 3860 KB Output is correct
4 Correct 80 ms 3860 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 2835 ms 509864 KB Output is correct
2 Correct 2687 ms 510024 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 44 ms 510024 KB Output is correct
2 Correct 44 ms 510024 KB Output is correct
3 Correct 42 ms 510024 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1358 ms 510024 KB Output is correct
2 Correct 1615 ms 510024 KB Output is correct
3 Correct 1461 ms 510024 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 2976 ms 511752 KB Output is correct
2 Correct 3100 ms 511768 KB Output is correct
3 Correct 3199 ms 511768 KB Output is correct