题解:HDU4879 ZCC loves march

题目

vjudge

You have a square grid of size $m×m$. There are $n$ troops placed on this grid, each with coordinates $(x_i​,y_i​)$.

Over t minutes, the following events occur:

  1. Move: A troop numbered x moves in a direction (up, down, left, or right) for d units. Troops cannot move outside the grid.

  2. Regroup: Troop x gathers all other troops that share the same row or column as troop x. These troops move to troop x’s location.

The cost of moving troop $i$ to troop $j$ is calculated as: $(x_i​−x_j​)^2+(y_i​−y_j​)^2$.

For each regrouping event, output the total cost of all troop movements during that regrouping, modulo $10^9+7$.


思路

我们对于每一个横坐标/纵坐标,记录下它们对应的纵坐标/横坐标(由于 $m$ 会很大,我们考虑把这些坐标离散化)。使用并查集,记录每一个士兵属于的块(即祖先节点),以及该块的大小。接下来开始操作。首先使用一个小技巧:对于每次操作,再开一个新点,这样就不用讨论该块的祖先节点是否改动。

对于操作1(对应下面操作S)非常好处理,将原来块大小减一,再将其放置到新快中;

对于操作2(对应下面操作Q),我们把当前士兵的位置作为新的块,依次遍历所有和它同行同列的块,这里要注意,对于与该士兵同样位置的士兵会在两次遍历中都被加入新块,要减一次。

想通这些部分,问题就迎刃而解了,只需模拟我们上述的思路即可。

Warnings:

  • 要看2倍数组

  • 要及时取模!中间会爆龙龙

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#include<bits/stdc++.h>

using namespace std;

#define ll long long

const int N=1e5+5,mod=1e9+7;

ll n,m,t;
struct node
{
ll x,y;
} a[N*2];

ll ans;
ll tox,toy;
map<ll,ll> mx,my;
vector<ll> ex[N*2],ey[N*2];
ll id[N];

ll cn[N*2],par[N*2];

ll find(ll x)
{
return par[x]==x?x:par[x]=find(par[x]);
}

int main()
{
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);

cin>>n>>m;
for(ll i=1;i<=n;i++)
{
cin>>a[i].x>>a[i].y;
id[i]=i;
if(!mx[a[i].x])
{
mx[a[i].x]=++tox;
}
if(!my[a[i].y])
{
my[a[i].y]=++toy;
}
ex[mx[a[i].x]].push_back(i);
ey[my[a[i].y]].push_back(i);
par[i]=i;
cn[i]++;
}

cin>>t;
for(ll i=n+1;i<=n+t;i++)
{
char c;
ll p;
cin>>c>>p;
p^=ans;
ll fp=find(id[p]);
ll cx=a[fp].x,cy=a[fp].y;
if(c=='Q')
{
ans=0;
a[i].x=cx,a[i].y=cy;
ll cn2=0;
for(auto q:ex[mx[cx]])
{
ll fq=find(q);
ll val=(a[fq].y-cy)%mod;
val=val*val%mod;
ans=(ans+val*cn[fq]%mod)%mod;
cn[i]+=cn[fq];
if(a[fq].y==cy) //count twice
{
cn2+=cn[fq];
}
else
{
par[fq]=i;
}
}
ex[mx[cx]].clear();
for(auto q:ey[my[cy]])
{
ll fq=find(q);
ll val=(a[fq].x-cx)%mod;
val=val*val%mod;
ans=(ans+val*cn[fq]%mod)%mod;
cn[i]+=cn[fq];
if(a[fq].x!=cx)
{
par[fq]=i;
}
}
ey[my[cy]].clear();
cn[i]-=cn2;
ex[mx[cx]].push_back(i);
ey[my[cy]].push_back(i);
par[i]=i;
cout<<ans<<"\n";
}
else
{
ll d;
cin>>d;
if(c=='L')
{
cy-=d;
}
else if(c=='R')
{
cy+=d;
}
else if(c=='U')
{
cx-=d;
}
else if(c=='D')
{
cx+=d;
}

if(!mx[cx])
{
mx[cx]=++tox;
}
if(!my[cy])
{
my[cy]=++toy;
}
a[i]={cx,cy};
cn[fp]--;
ex[mx[cx]].push_back(i);
ey[my[cy]].push_back(i);
cn[i]++;
par[i]=i;
}
id[p]=i;
}

return 0;
}

做了我2d,纯纯可恶 (σ`д′)σ

作者

Olivia_uu

发布于

2025-02-08

更新于

2025-02-11

许可协议

You need to set install_url to use ShareThis. Please set it in _config.yml.

评论

Your browser is out-of-date!

Update your browser to view this website correctly.&npsb;Update my browser now

×