您的位置:首页 > 理论基础 > 数据结构算法

HDU 4879 ZCC loves march (2014多校2-1008,数据结构,STL,模拟题)

2014-07-27 00:57 423 查看
题目:

http://acm.hdu.edu.cn/showproblem.php?pid=4879

题意:

给一个n*m的矩阵,有n个人,t次操作,操作有以下两种:

1、令编号x的人上下左右移动

2、令与编号x的人同行同列的人聚集到x这里,输出花费

方法:

使用两个set,一个维护x轴,一个维护y轴

一个map<point,int>,表示这一个point有多少个人

然后根据要求的操作直接操作即可,nlgn复杂度

注意:

1、由于set或者map是红黑树,所以删除节点的后,内部节点重排,it++会变化,需要重新查询给迭代器it赋值,这里一直RE

2、计算两者距离时,计算xi-xj和yi-yj时需要mod,否则乘起来会爆long long

代码:

// #pragma comment(linker, "/STACK:102400000,102400000")
#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <cmath>
#include <set>
#include <list>
#include <map>
#include <iterator>
#include <cstdlib>
#include <vector>
#include <queue>
#include <stack>
#include <algorithm>
#include <functional>
using namespace std;
typedef long long LL;
#define ROUND(x) round(x)
#define FLOOR(x) floor(x)
#define CEIL(x) ceil(x)
const int maxn = 100010;
const int maxm = 0;
const LL mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const LL inf64 = 0x3f3f3f3f3f3f3f3fLL;
const double INF = 1e30;
const double eps = 1e-6;
const int P[4] = {0, 0, -1, 1};
const int Q[4] = {1, -1, 0, 0};
const int PP[8] = { -1, -1, -1, 0, 0, 1, 1, 1};
const int QQ[8] = { -1, 0, 1, -1, 1, -1, 0, 1};
LL n, m;
LL ans = 0;
int id;
LL d;
struct Point
{
LL x, y;
int id;
Point(LL _x = -1, LL _y = -1, int _id = -1): x(_x), y(_y), id(_id) {}
bool operator == (const Point &o) const
{
return x == o.x && y == o.y;
}
} node[maxn];
struct cmp1
{
bool operator () (const Point &A, const Point &B) const
{
if (A.x == B.x) return A.y < B.y;
return A.x < B.x;
}
};
struct cmp2
{
bool operator () (const Point &A, const Point &B) const
{
if (A.y == B.y) return A.x < B.x;
return A.y < B.y;
}
};
set<Point, cmp1> s1;
set<Point, cmp2> s2;
map<Point, int, cmp1> mp;
void debug()
{
cout << "debug:" << endl;
cout << "s1:" << endl;
for (set<Point>::iterator it = s1.begin(); it != s1.end(); it++)
{
cout << it->x << " " << it->y << endl;
}
cout << "s2:" << endl;
for (set<Point>::iterator it = s2.begin(); it != s2.end(); it++)
{
cout << it->x << " " << it->y << endl;
}
cout << "mp:" << endl;
for (map<Point, int>::iterator it = mp.begin(); it != mp.end(); it++)
{
cout << it->first.x << " " << it->first.y << " " << it->second << endl;
}
cout << endl;
}
void init()
{
mp.clear();
s1.clear();
s2.clear();
ans = 0;
}
void add(Point p)
{
if (mp.count(p) == 0)
{
mp[p] = 1;
s1.insert(p);
s2.insert(p);
}
else mp[p]++;
}
void del(Point p)
{
map<Point, int, cmp1>::iterator ite = mp.find(p);
ite->second--;
if (ite->second == 0)
{
mp.erase(ite);
s1.erase(p);
s2.erase(p);
}
}
void input()
{
s1.insert(Point(-1, 0));
s1.insert(Point(m + 1, 0));
s2.insert(Point(0, -1));
s2.insert(Point(0, m + 1));
// s2.insert(Point(0, m + 2));
for (LL i = 1; i <= n; i++)
{
scanf("%I64d%I64d", &node[i].x, &node[i].y);
node[i].id = i;
add(node[i]);
}
}
LL dis(Point a, Point b)
{
return ((((a.x - b.x) % mod) * ((a.x - b.x) % mod) % mod) + (((a.y - b.y) % mod) * ((a.y - b.y) % mod) % mod)) % mod;
}
void exq()
{
ans = 0;
Point tt = node[id];
map<Point, int, cmp1>::iterator ite = mp.find(tt);

set<Point, cmp1>::iterator it1 = s1.find(tt);
set<Point, cmp1>::iterator L1 = it1, R1 = it1;
for (; L1->x == it1->x; --L1); ++L1;
for (; R1->x == it1->x; ++R1);
for (set<Point, cmp1>::iterator it = L1; it != R1;)
{
// cout << "it1: " << it->x << " " << it->y << endl;
if (it == it1)
{
it++;
continue;
}
Point nt = *it;

node[it->id] = tt;
int cnt = mp[nt];
ans += cnt * dis(tt, nt) % mod;
ans %= mod;
ite->second += cnt;
it++;
Point ntt = *it;
mp.erase(nt);
s1.erase(nt);
s2.erase(nt);
it = s1.find(ntt);
}

set<Point, cmp2>::iterator it2 = s2.find(tt);
set<Point, cmp2>::iterator L2 = it2, R2 = it2;
for (; L2->y == it2->y; --L2); ++L2;
for (; R2->y == it2->y; ++R2);
// cout << "R2: " << R2->x << " " << R2->y << endl;
for (set<Point, cmp2>::iterator it = L2; it != R2;)
{
// cout << "it2: " << it->x << " " << it->y << endl;
// if (it == R2) break;
if (it == it2)
{
it++;
continue;
}
Point nt = *it;
node[it->id] = tt;
int cnt = mp[nt];
ans += cnt * dis(tt, nt) % mod;
ans %= mod;
ite->second += cnt;
//set<Point, cmp2>::iterator tmp = it;
it++;
Point ntt = *it;
mp.erase(nt);
s1.erase(nt);
s2.erase(nt);
it = s2.find(ntt);
}

printf("%I64d\n", ans);
}
void exu()
{
Point pre = node[id];
Point now = Point(pre.x - d, pre.y, pre.id);
node[id] = now;
del(pre);
add(now);
}
void exd()
{
Point pre = node[id];
Point now = Point(pre.x + d, pre.y, pre.id);
node[id] = now;
del(pre);
add(now);
}
void exl()
{
Point pre = node[id];
Point now = Point(pre.x , pre.y - d, pre.id);
node[id] = now;
del(pre);
add(now);
}
void exr()
{
Point pre = node[id];
Point now = Point(pre.x , pre.y + d, pre.id);
node[id] = now;
del(pre);
add(now);
}
void solve()
{
int T;
scanf("%d", &T);
char str[10];
while (T--)
{
// debug();
scanf("%s", str);
// puts(str);
if (str[0] == 'Q')
{
scanf("%d", &id);
id ^= (int)ans;
// cout << "id: " << ans << " " << id << endl;
exq();
}
else
{
scanf("%d%I64d", &id, &d);
id ^= (int)ans;
// cout << "id: " << ans << " " << id << endl;
if (str[0] == 'U')
exu();
else if (str[0] == 'D')
exd();
else if (str[0] == 'L')
exl();
else
exr();
}
// debug();
}
}
void output()
{
//
}
int main()
{
// std::ios_base::sync_with_stdio(false);
// #ifndef ONLINE_JUDGE
//     freopen("in.cpp", "r", stdin);
// #endif

while (~scanf("%I64d%I64d", &n, &m))
{
init();
input();
solve();
output();
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: