码迷,mamicode.com
首页 > 其他好文 > 详细

haha

时间:2015-11-11 13:11:07      阅读:241      评论:0      收藏:0      [点我收藏+]

标签:

#pragma warning(disable:4996)
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cmath>
#include <queue>
#include <cstdlib>
using namespace std;
 
#define maxn 51000
#define dim 5
 
namespace KDTree
{
    int K;
    struct Point
    {
        int x[dim];
        void input(){
            for (int i = 0; i < K; ++i){
                scanf("%d", x + i);
            }
        }
        void output(){
            for (int i = 0; i < K; ++i){
                if (i) printf(" ");
                printf("%d", x[i]);
            }
            puts("");
        }
        double dist(const Point &b){
            double sum = 0;
            for (int i = 0; i < K; ++i) sum += (x[i] - b.x[i])*(x[i] - b.x[i]);
            return sqrt(sum);
        }
    };
 
    struct qnode{
        Point p;
        double dis;
        qnode(){};
        qnode(Point _p, double _dis) :p(_p), dis(_dis){}
        bool operator  < (const qnode &b) const{
            return dis < b.dis;
        }
    };
 
    priority_queue<qnode> que;
 
    struct cmpx
    {
        int div;
        cmpx(int _div) :div(_div){}
        bool operator()(const Point &a, const Point &b){
            for (int i = 0; i < K; ++i){
                if (a.x[(div + i) % K] != b.x[(div + i) % K]) return a.x[(div + i) % K] < b.x[(div + i) % K];
            }
            return true;
        }
    };
 
    bool cmp(const Point &a, const Point &b, int div){
        cmpx cp = cmpx(div);
        return cp(a, b);
    }
 
    struct Node
    {
        Point e;
        Node *lc, *rc;
        int div;
    }pool[maxn], *tail, *root;
    void init(){
        tail = pool;
    }
 
    Node *build(Point *a, int l, int r, int div)
    {
        if (l >= r) return NULL;
        Node *p = tail++;
        p->div = div;
        int mid = (l + r) >> 1;
        nth_element(a + l, a + mid, a + r, cmpx(div));
        p->e = a[mid];
        p->lc = build(a, l, mid, (div + 1) % K);
        p->rc = build(a, mid + 1, r, (div + 1) % K);
        return p;
    }
 
    void search(Point p, Node *x, int div, int m)
    {
        if (!x) return;
        if (cmp(p, x->e, div)){
            search(p, x->lc, (div + 1) % K, m);
            if (que.size() < m){
                que.push(qnode(x->e, p.dist(x->e)));
                search(p, x->rc, (div + 1) % K, m);
            }
            else{
                if (p.dist(x->e) < que.top().dis){
                    que.pop();
                    que.push(qnode(x->e, p.dist(x->e)));
                }
                if (fabs(x->e.x[div] - p.x[div] + .0) < que.top().dis){
                    search(p, x->rc, (div + 1) % K, m);
                }
            }
        }
        else{
            search(p, x->rc, (div + 1) % K, m);
            if (que.size() < m){
                que.push(qnode(x->e, p.dist(x->e)));
                search(p, x->lc, (div + 1) % K, m);
            }
            else{
                if (p.dist(x->e) < que.top().dis){
                    que.pop();
                    que.push(qnode(x->e, p.dist(x->e)));
                }
                if (fabs(x->e.x[div] - p.x[div] + .0) < que.top().dis){
                    search(p, x->lc, (div + 1) % K, m);
                }
            }
        }
    }
 
    void search(Point p, int m)
    {
        while (!que.empty()) que.pop();
        search(p, root, 0, m);
    }
};
 
KDTree::Point p[maxn];
 
int main()
{
    int n, k;
    while (cin >> n >> k)
    {
        KDTree::K = k;
        for (int i = 0; i < n; ++i) p[i].input();
        KDTree::init();
        KDTree::root = build(p, 0, n, 0);
        int Q;
        cin >> Q;
        while (Q--)
        {
            KDTree::Point qpoint;
            qpoint.input();
            int m;
            scanf("%d", &m);
            KDTree::search(qpoint, m);
            printf("the closest %d points are:\n", m);
            int cnt = 0;
            while (!KDTree::que.empty()){
                p[cnt++] = KDTree::que.top().p;
                KDTree::que.pop();
            }
            for (int i = m - 1; i >= 0; --i){
                p[i].output();
            }
        }
    }
    return 0;
}
#include <iostream>
#include <cstring>
#include <vector>
#include <algorithm>
#include <cmath>
#include <ctime>
using namespace std;

#define ll long long
#define mod 1000000007

ll mod_pow(ll a, ll n, ll mo)
{
	ll ret = 1;
	while (n){
		if (n & 1) ret = ret*a%mo;
		a = a*a%mo;
		n >>= 1;
	}
	return ret;
}

ll inv2 = mod_pow(2, mod - 2, mod);

void fwt_xor(ll a[], int l, int r)
{
	if (l == r) return;
	int mid = (l + r) >> 1;
	fwt_xor(a, l, mid);
	fwt_xor(a, mid + 1, r);
	int len = mid - l + 1;
	for (int i = l; i <= mid; ++i){
		ll x1 = a[i];
		ll x2 = a[i + len];
		a[i] = (x1 + x2) % mod;
		a[i + len] = (x1 - x2 + mod) % mod;
	}
}

void ifwt_xor(ll a[], int l, int r)
{
	if (l == r) return;
	int mid = (l + r) >> 1;
	int len = mid - l + 1;
	for (int i = l; i <= mid; ++i){
		// y1=x1+x2
		// y2=x1-x2
		ll y1 = a[i];
		ll y2 = a[i + len];
		a[i] = (y1 + y2)*inv2 % mod;
		a[i + len] = ((y1 - y2 + mod) % mod*inv2) % mod;
	}
	ifwt_xor(a, l, mid);
	ifwt_xor(a, mid + 1, r);
}

void fwt_and(ll a[], int l, int r)
{
	if (l == r) return;
	int mid = (l + r) >> 1;
	fwt_and(a, l, mid);
	fwt_and(a, mid + 1, r);
	int len = mid - l + 1;
	for (int i = l; i <= mid; ++i){
		ll x1 = a[i];
		ll x2 = a[i + len];
		a[i] = (x1 + x2) % mod;
		a[i + len] = x2 % mod;
	}
}

void ifwt_and(ll a[], int l, int r)
{
	if (l == r) return;
	int mid = (l + r) >> 1;
	int len = mid - l + 1;
	for (int i = l; i <= mid; ++i){
		// y1=x1+x2
		// y2=x2
		ll y1 = a[i];
		ll y2 = a[i + len];
		a[i] = (y1 - y2 + mod ) % mod;
		a[i + len] = y2 % mod;
	}
	ifwt_and(a, l, mid);
	ifwt_and(a, mid + 1, r);
}

void fwt_or(ll a[], int l, int r)
{
	if (l == r) return;
	int mid = (l + r) >> 1;
	fwt_or(a, l, mid);
	fwt_or(a, mid + 1, r);
	int len = mid - l + 1;
	for (int i = l; i <= mid; ++i){
		ll x1 = a[i];
		ll x2 = a[i + len];
		a[i] = x1 % mod;
		a[i + len] = (x2+x1) % mod;
	}
}

void ifwt_or(ll a[], int l, int r)
{
	if (l == r) return;
	int mid = (l + r) >> 1;
	int len = mid - l + 1;
	for (int i = l; i <= mid; ++i){
		// y1=x1
		// y2=x2+x1
		ll y1 = a[i];
		ll y2 = a[i + len];
		a[i] = y1 % mod;
		a[i + len] = (y2 - y1 + mod) % mod;
	}
	ifwt_or(a, l, mid);
	ifwt_or(a, mid + 1, r);
}


const int maxn = 1024;
bool test_xor()
{
	ll a1[maxn], a2[maxn];
	ll b1[maxn], b2[maxn];
	for (int i = 0; i < maxn; ++i){
		a1[i] = a2[i] = rand();
		b1[i] = b2[i] = rand();
	}
	ll c1[maxn];
	ll c2[maxn];
	memset(c1, 0, sizeof(c1));
	memset(c2, 0, sizeof(c2));

	for (int i = 0; i < maxn; ++i){
		for (int j = 0; j < maxn; ++j){
			c1[i^j] += (a1[i] * b1[j]) % mod;
			c1[i^j] %= mod;
		}
	}

	fwt_xor(a2, 0, maxn - 1);
	fwt_xor(b2, 0, maxn - 1);
	for (int i = 0; i < maxn; ++i){
		c2[i] = a2[i] * b2[i] % mod;
	}
	ifwt_xor(c2, 0, maxn - 1);

	for (int i = 0; i < maxn; ++i){
		if (c1[i] != c2[i]){
			return false;
		}
	}
	return true;
}

bool test_and()
{
	ll a1[maxn], a2[maxn];
	ll b1[maxn], b2[maxn];
	for (int i = 0; i < maxn; ++i){
		a1[i] = a2[i] = rand();
		b1[i] = b2[i] = rand();
	}
	ll c1[maxn];
	ll c2[maxn];
	memset(c1, 0, sizeof(c1));
	memset(c2, 0, sizeof(c2));

	for (int i = 0; i < maxn; ++i){
		for (int j = 0; j < maxn; ++j){
			c1[i&j] += (a1[i] * b1[j]) % mod;
			c1[i&j] %= mod;
		}
	}

	fwt_and(a2, 0, maxn - 1);
	fwt_and(b2, 0, maxn - 1);
	for (int i = 0; i < maxn; ++i){
		c2[i] = a2[i] * b2[i] % mod;
	}
	ifwt_and(c2, 0, maxn - 1);

	for (int i = 0; i < maxn; ++i){
		if (c1[i] != c2[i]){
			return false;
		}
	}
	return true;
}

bool test_or()
{
	ll a1[maxn], a2[maxn];
	ll b1[maxn], b2[maxn];
	for (int i = 0; i < maxn; ++i){
		a1[i] = a2[i] = rand();
		b1[i] = b2[i] = rand();
	}
	ll c1[maxn];
	ll c2[maxn];
	memset(c1, 0, sizeof(c1));
	memset(c2, 0, sizeof(c2));

	for (int i = 0; i < maxn; ++i){
		for (int j = 0; j < maxn; ++j){
			c1[i|j] += (a1[i] * b1[j]) % mod;
			c1[i|j] %= mod;
		}
	}

	fwt_or(a2, 0, maxn - 1);
	fwt_or(b2, 0, maxn - 1);
	for (int i = 0; i < maxn; ++i){
		c2[i] = a2[i] * b2[i] % mod;
	}
	ifwt_or(c2, 0, maxn - 1);

	for (int i = 0; i < maxn; ++i){
		if (c1[i] != c2[i]){
			return false;
		}
	}
	return true;
}


int main()
{
	srand(time(0));
	if (test_xor()){
		puts("test_xor succ.");
	}
	else{
		puts("test_xor fail");
	}

	if (test_and()){
		puts("test_and succ.");
	}
	else{
		puts("test_and fail");
	}

	if (test_or()){
		puts("test_or succ.");
	}
	else{
		puts("test_or fail");
	}

	system("pause");
}

  

haha

标签:

原文地址:http://www.cnblogs.com/chanme/p/4877334.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!