
 /**//*
N行,有M个僵尸,有K个坚果,按顺序从给定线路水平滚出
坚果撞到僵尸或者边界都会改变路线以45°滚动,问最后多少只僵尸被撞到了
N<=2000, M<=200000, K<=100000
我之前是按顺序模拟坚果滚动,超时了
虽然我也是建了list之类的,我知道的是能用x+y,x-y的值来表示直线
复杂度应该是O(MlogM + K)

watashi解题报告说可以用链表类似Dancing Links啥的搞到O(M+K),但是编程量巨大
他自己的做法很神奇!!!!
反过来做,对僵尸按X排序,从左到右,检查该僵尸会被哪只坚果撞到(其实就是被编号最小的撞到)
一只僵尸(x,y)可以被3个方向撞到(y=1,n时两个),路线的方程就是
x - y = k1 , x + y = k2 , y = k3
因此需要找到满足上面方程之一的坚果,而且编号最小的
直接这样搞,方程很多的,我之前就是这样子搞 ..

注意到x-y = k1与x-2(n-1)-y=k1是同一条路线的,所以可以对(x-y)%2(n-1),x+y也一样
取模了后本来x-y很大的,就变为很小了,而且是可唯一标示出来的
两个点A,B若在同一条路线上,若他们都向下或向上的话,显然
y1-x1 = y2-x2 mod m , m-(y1+x1) = m-(y2+x2) mod m
若一上一下,就 y1-x1 = m-(y2+x2) mod m
这样一条路线就能用一个值来表示了,即在点(x,y)处,
----------------------------------------------
|若向下则该路线的值(y-x) mod m |
|若向上则该路线的值m-(y+x) mod m |
----------------------------------------------
为什么能这样表示呢?
比如向下的直线方程为y-x = k1,向上的为y+x=k2
他们关于边界对称,则有k1+k2 = m,即k1 = m - k2,所以用K1,m-k2就能唯一表示线路了(曲折的,不是直线)
\ /
\/
------- m/2 下面的那个是引出的,上面的是实际路线,显然这两条直线跟y轴的交点之和k1+k2为m
/
/

在起始处总共也就只会有n-1条向下的,n-1条向上的,n条水平的,这2*(n-1)+n条直线就会铺满整个地图了
因此可编码为 [0,n-1)的为向下的,[n-1,2(n-1))向上的,[2*(n-1),3*n-2)水平的

启示:处理好同一条路线怎么用一个值来表示

枚举点(x,y)可能被几个方向撞到的线路,这些路线就是m+y, (y-x) mod m , m-(y+x) mod m
最后就用优先队列来搞,取编号最小的路线,因为最先被这个撞到了~~~
处理好一列后,注意加入新的坚果路线(因为撞了后改变路线了)

神奇丫神奇丫~~~~


以上只是我膜拜了watashi的代码后的一点想法而已,建议直接看他的代码~~~
*/
#include<iostream>
#include<cstring>
#include<map>
#include<algorithm>
#include<stack>
#include<queue>
#include<cmath>
#include<string>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<set>
#include<list>
#include<numeric>
#include<cassert>
#include<ctime>
#include<bitset>

using namespace std;

const int MAXN =200000;

pair<int,int> pt[MAXN];
priority_queue<int, vector<int>, greater<int> > pq[6000];//最小堆

 inline int mod(int a, int b) {
a %= b;
return a < 0 ? a + b : a;
}

int main()
  {
#ifndef ONLINE_JUDGE
freopen("in","r",stdin);
#endif

int T, N, M, K;
 for(scanf("%d", &T); T--; ) {
scanf("%d%d%d", &N, &M, &K);
int m = 2*(N-1);

 for(int k = 0; k < m + N ; k++) {
 while(!pq[k].empty()) {
pq[k].pop();
}
}

 for (int i = 0; i < M; i ++) {
scanf("%d%d", &pt[i].first, &pt[i].second);
pt[i].second --;
}
sort(pt, pt+M);

 for (int i = 0, t; i < K; i ++) {
scanf("%d", &t);
pq[m+t-1].push(i);
}
int lastx = 0, ans = 0;
vector<pair<int,int> > r;
 for(int i = 0; i < M; i ++) {
int x = pt[i].first , y = pt[i].second;
 if (x > lastx) {//处理完一列后注意加入新的坚果路线
lastx = x;
 for (vector<pair<int,int> >::iterator it = r.begin() ; it != r.end(); it ++) {
pq[it->first].push(it->second);
}
r.clear();
}

int j = -1, t;
 if(!pq[t = m+y].empty() && (j == -1 || pq[t].top() < pq[j].top())) {// horizonal
j = t;
}
 if(!pq[t = mod(y-x, m)].empty() && ( j == -1 || pq[t].top() < pq[j].top()) ) { //buttom right
j = t;
}
 if(!pq[t = mod(m-(y+x), m)].empty() && ( j == -1 || pq[t].top() < pq[j].top()) ) { //top right
j = t;
}
 if(j == -1) {
continue;
}

ans ++;
t = pq[j].top();
pq[j].pop();
 if(j < m) {
r.push_back(make_pair(mod(m-j-2*x, m),t));
 }else {
j -= m;
 if(j < N/2) {//buttom right
r.push_back(make_pair(mod(y-x,m),t));
 } else {//top right
r.push_back(make_pair(mod(m-(y+x),m),t));
}
}
}
printf("%d\n" , ans);
}
return 0;
}
|
|
常用链接
随笔分类
Links
搜索
最新评论

|
|